Passed
Push — master ( 69958c...d88402 )
by Andreas
23:02
created

midgard_admin_asgard_schemadb_config::create()   B

Complexity

Conditions 11
Paths 60

Size

Total Lines 54
Code Lines 33

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 30
CRAP Score 11.1967

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 11
eloc 33
c 1
b 0
f 0
nc 60
nop 0
dl 0
loc 54
ccs 30
cts 34
cp 0.8824
crap 11.1967
rs 7.3166

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * @package midgard.admin.asgard
4
 * @author CONTENT CONTROL http://www.contentcontrol-berlin.de/
5
 * @copyright CONTENT CONTROL http://www.contentcontrol-berlin.de/
6
 * @license http://www.gnu.org/licenses/gpl.html GNU General Public License
7
 */
8
9
use midcom\datamanager\schemadb;
10
use midcom\datamanager\validation\phpValidator;
11
12
/**
13
 * Helper class to create a DM schema from component's config
14
 *
15
 * @package midgard.admin.asgard
16
 */
17
class midgard_admin_asgard_schemadb_config
18
{
19
    private string $component;
20
21
    private midcom_helper_configuration $config;
22
23
    private bool $is_folder;
24
25 2
    public function __construct(string $component, midcom_helper_configuration $config, bool $is_folder)
26
    {
27 2
        $this->component = $component;
28 2
        $this->config = $config;
29 2
        $this->is_folder = $is_folder;
30
    }
31
32 2
    public function create() : schemadb
33
    {
34
        // Load SchemaDb
35 2
        $schemaname = 'default';
36
37 2
        if ($path = $this->config->get('schemadb_config')) {
38 2
            $schemadb = schemadb::from_path($path);
39 2
            if ($schemadb->has('config')) {
40 2
                $schemaname = 'config';
41
            }
42
        } else {
43
            // Create dummy schema. Naughty component would not provide config schema.
44
            $schemadb = new schemadb(['default' => [
45
                'description' => 'configuration for ' . $this->component,
46
                'fields'      => []
47
            ]]);
48
        }
49 2
        $schema = $schemadb->get($schemaname);
50 2
        $schema->set('l10n_db', $this->component);
51 2
        $fields = $schema->get('fields');
52
53 2
        foreach ($this->config->_global as $key => $value) {
54
            // try to sniff what fields are missing in schema
55 2
            if (!array_key_exists($key, $fields)) {
56 2
                $fields[$key] = $this->detect_schema($key, $value);
57
            }
58
59 2
            if (   !isset($this->config->_local[$key])
60 2
                || $this->config->_local[$key] == $this->config->_global[$key]) {
61
                // No local configuration setting, note to user that this is the global value
62 2
                $fields[$key]['title'] = $schema->get_l10n()->get($fields[$key]['title']);
63 2
                $fields[$key]['title'] .= " <span class=\"global\">(" . midcom::get()->i18n->get_string('global value', 'midgard.admin.asgard') .")</span>";
64
            }
65
        }
66
67
        // Prepare defaults
68 2
        $config = array_intersect_key($this->config->get_all(), $fields);
69 2
        foreach ($config as $key => $value) {
70 2
            if (is_array($value)) {
71 2
                $fields[$key]['default'] = var_export($value, true);
72
            } else {
73 2
                if ($fields[$key]['widget'] == 'checkbox') {
74 2
                    $value = (boolean) $value;
75
                }
76 2
                $fields[$key]['default'] = $value;
77
            }
78
        }
79 2
        $schema->set('fields', $fields);
80 2
        $validation = $schema->get('validation') ?: [];
81 2
        $validation[] = [
82 2
            'callback' => $this->check_config(...),
83 2
        ];
84 2
        $schema->set('validation', $validation);
85 2
        return $schemadb;
86
    }
87
88 2
    private function detect_schema(string $key, $value) : array
89
    {
90 2
        $result = [
91 2
            'title'  => $key,
92 2
            'type'   => 'text',
93 2
            'widget' => 'text',
94 2
        ];
95
96 2
        $type = gettype($value);
97
        switch ($type) {
98 2
            case "boolean":
99 2
                $result['type'] = 'boolean';
100 2
                $result['widget'] = 'checkbox';
101 2
                break;
102 2
            case "array":
103 2
                $result['widget'] = 'textarea';
104
                // Complex Array fields should be readonly for topics as we cannot store and read them properly with parameters
105 2
                $result['readonly'] = $this->is_folder;
106 2
                break;
107 2
            case 'string':
108 2
                if (str_contains($value, "\n")) {
109
                    $result['widget'] = 'textarea';
110
                }
111
        }
112
113 2
        return $result;
114
    }
115
116
    /**
117
     * Ensure the configuration is valid (form validation callback)
118
     */
119
    public function check_config(array $values)
120
    {
121
        $current = $this->config->get_all();
122
        $result = [];
123
        foreach ($values as $key => $newval) {
124
            if ($newval === '' || !isset($current[$key])) {
125
                continue;
126
            }
127
            $val = $current[$key];
128
129
            if (is_array($val)) {
130
                $code = "<?php\n\$data = array({$newval}\n);\n?>";
131
                if ($error = phpValidator::lint($code)) {
132
                    $result[$key] = $error;
133
                }
134
            }
135
        }
136
        return $result ?: true;
137
    }
138
}