Passed
Push — master ( 73547b...a0a706 )
by Andreas
36:17
created

midgard_admin_asgard_schemadb_config::create()   B

Complexity

Conditions 11
Paths 60

Size

Total Lines 56
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 29
CRAP Score 11.0995

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 11
eloc 34
c 1
b 0
f 0
nc 60
nop 0
dl 0
loc 56
ccs 29
cts 32
cp 0.9063
crap 11.0995
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 $component;
20
21
    /**
22
     * @var midcom_helper_configuration
23
     */
24
    private $config;
25
26
    private $is_folder;
27
28 2
    public function __construct(string $component, midcom_helper_configuration $config, bool $is_folder)
29
    {
30 2
        $this->component = $component;
31 2
        $this->config = $config;
32 2
        $this->is_folder = $is_folder;
33 2
    }
34
35 2
    public function create() : schemadb
36
    {
37
        // Load SchemaDb
38 2
        $schemadb_config_path = midcom::get()->componentloader->path_to_snippetpath($this->component) . '/config/config_schemadb.inc';
39 2
        $schemaname = 'default';
40
41 2
        if (file_exists($schemadb_config_path)) {
42
            $schemadb = schemadb::from_path('file:/' . str_replace('.', '/', $this->component) . '/config/config_schemadb.inc');
43
            if ($schemadb->has('config')) {
44
                $schemaname = 'config';
45
            }
46
            // TODO: Log error on deprecated config schema?
47
        } else {
48
            // Create dummy schema. Naughty component would not provide config schema.
49 2
            $schemadb = new schemadb(['default' => [
50 2
                'description' => 'configuration for ' . $this->component,
51
                'fields'      => []
52
            ]]);
53
        }
54 2
        $schema = $schemadb->get($schemaname);
55 2
        $schema->set('l10n_db', $this->component);
56 2
        $fields = $schema->get('fields');
57
58 2
        foreach ($this->config->_global as $key => $value) {
59
            // try to sniff what fields are missing in schema
60 2
            if (!array_key_exists($key, $fields)) {
61 2
                $fields[$key] = $this->detect_schema($key, $value);
62
            }
63
64 2
            if (   !isset($this->config->_local[$key])
65 2
                || $this->config->_local[$key] == $this->config->_global[$key]) {
66
                // No local configuration setting, note to user that this is the global value
67 2
                $fields[$key]['title'] = $schema->get_l10n()->get($fields[$key]['title']);
68 2
                $fields[$key]['title'] .= " <span class=\"global\">(" . midcom::get()->i18n->get_string('global value', 'midgard.admin.asgard') .")</span>";
69
            }
70
        }
71
72
        // Prepare defaults
73 2
        $config = array_intersect_key($this->config->get_all(), $fields);
74 2
        foreach ($config as $key => $value) {
75 2
            if (is_array($value)) {
76 2
                $fields[$key]['default'] = var_export($value, true);
77
            } else {
78 2
                if ($fields[$key]['widget'] == 'checkbox') {
79 2
                    $value = (boolean) $value;
80
                }
81 2
                $fields[$key]['default'] = $value;
82
            }
83
        }
84 2
        $schema->set('fields', $fields);
85 2
        $validation = $schema->get('validation') ?: [];
86 2
        $validation[] = [
87 2
            'callback' => [$this, 'check_config'],
88
        ];
89 2
        $schema->set('validation', $validation);
90 2
        return $schemadb;
91
    }
92
93 2
    private function detect_schema(string $key, $value) : array
94
    {
95
        $result = [
96 2
            'title'  => $key,
97 2
            'type'   => 'text',
98 2
            'widget' => 'text',
99
        ];
100
101 2
        $type = gettype($value);
102 2
        switch ($type) {
103 2
            case "boolean":
104 2
                $result['type'] = 'boolean';
105 2
                $result['widget'] = 'checkbox';
106 2
                break;
107 2
            case "array":
108 2
                $result['widget'] = 'textarea';
109
                // Complex Array fields should be readonly for topics as we cannot store and read them properly with parameters
110 2
                $result['readonly'] = $this->is_folder;
111 2
                break;
112 2
            case 'string':
113 2
                if (preg_match("/\n/", $value)) {
114
                    $result['widget'] = 'textarea';
115
                }
116
        }
117
118 2
        return $result;
119
    }
120
121
    /**
122
     * Ensure the configuration is valid (form validation callback)
123
     */
124
    public function check_config(array $values)
125
    {
126
        $current = $this->config->get_all();
127
        $result = [];
128
        foreach ($values as $key => $newval) {
129
            if ($newval === '' || !isset($current[$key])) {
130
                continue;
131
            }
132
            $val = $current[$key];
133
134
            if (is_array($val)) {
135
                $code = "<?php\n\$data = array({$newval}\n);\n?>";
136
                if ($error = phpValidator::lint($code)) {
137
                    $result[$key] = $error;
138
                }
139
            }
140
        }
141
        return $result ?: true;
142
    }
143
}