Passed
Push — master ( 0cded3...9172b1 )
by Andreas
97:58
created

midgard_admin_asgard_schemadb::create()   C

Complexity

Conditions 14
Paths 88

Size

Total Lines 80
Code Lines 54

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 32
CRAP Score 17.9747

Importance

Changes 0
Metric Value
cc 14
eloc 54
nc 88
nop 1
dl 0
loc 80
ccs 32
cts 44
cp 0.7272
crap 17.9747
rs 6.2666
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A midgard_admin_asgard_schemadb::_add_name_field() 0 20 3
B midgard_admin_asgard_schemadb::add_longtext_field() 0 17 9
A midgard_admin_asgard_schemadb::_add_component_dropdown() 0 21 3

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\schemabuilder;
10
11
/**
12
 * Helper class to create a DM schema from an object via reflection
13
 *
14
 * @package midgard.admin.asgard
15
 */
16
class midgard_admin_asgard_schemadb extends schemabuilder
17
{
18
    /**
19
     * Component config for Asgard
20
     *
21
     * @var midcom_helper_configuration
22
     */
23
    private $_config;
24
25
    /**
26
     * @var midcom_services_i18n_l10n
27
     */
28
    private $l10n;
29
30
    /**
31
     * Flag that controls if fields used for copying should be added
32
     *
33
     * @var boolean
34
     */
35
    public $add_copy_fields = false;
36
37 31
    public function __construct(midcom_core_dbaobject $object, midcom_helper_configuration $config)
38
    {
39 31
        parent::__construct($object);
40 31
        $this->_config = $config;
41 31
        $this->l10n = midcom::get()->i18n->get_l10n('midgard.admin.asgard');
42 31
    }
43
44
    /**
45
     * Generates, loads and prepares the schema database.
46
     *
47
     * The operations are done on all available schemas within the DB.
48
     */
49 9
    protected function process_type(string $type, array $type_fields)
50
    {
51 9
        usort($type_fields, [$this, 'sort_schema_fields']);
52
53 9
        parent::process_type($type, $type_fields);
54
55 9
        $this->_add_rcs_field();
56
57 9
        if ($this->add_copy_fields) {
58 2
            $this->_add_copy_fields();
59
        }
60 9
        if (empty($this->schema['l10n_db'])) {
61
            $this->schema['l10n_db'] = 'midgard.admin.asgard';
62
        }
63 9
    }
64
65 7
    protected function add_string_field(string $key, string $type)
66
    {
67 7
        if (   $key == 'component'
68 7
            && $type == midcom_db_topic::class) {
69 5
            $this->_add_component_dropdown($key);
70 5
            return;
71
        }
72
73
        // Special name handling, start by checking if given type is same as $this->object and if not making a dummy copy (we're probably in creation mode then)
74 7
        if ($this->object instanceof $type) {
75 7
            $name_obj = $this->object;
76
        } else {
77
            $name_obj = new $type();
78
        }
79
80 7
        if ($key === midcom_helper_reflector::get_name_property($name_obj)) {
81 7
            $this->_add_name_field($key, $name_obj);
82 7
            return;
83
        }
84 7
        parent::add_string_field($key, $type);
85 7
    }
86
87 7
    private function _add_name_field(string $key, midcom_core_dbaobject $name_obj)
88
    {
89 7
        $type_urlname_config = [];
90 7
        $allow_unclean_name_types = $this->_config->get('allow_unclean_names_for');
91 7
        foreach ($allow_unclean_name_types as $allow_unclean_name_types_type) {
92 7
            if ($name_obj->__object instanceof $allow_unclean_name_types_type) {
93
                $type_urlname_config['allow_unclean'] = true;
94
                break;
95
            }
96
        }
97
98
        // Enable generating the name from the title property
99 7
        $type_urlname_config['title_field'] = midcom_helper_reflector::get_title_property($name_obj);
100
101 7
        $this->schema['fields'][$key] = [
102 7
            'title'       => $key,
103 7
            'storage'     => $key,
104 7
            'type'        => 'urlname',
105 7
            'type_config' => $type_urlname_config,
106 7
            'widget'      => 'text',
107
        ];
108 7
    }
109
110 5
    private function _add_component_dropdown(string $key)
111
    {
112 5
        $components = ['' => ''];
113 5
        foreach (midcom::get()->componentloader->get_manifests() as $manifest) {
114
            // Skip purecode components
115 5
            if ($manifest->purecode) {
116 5
                continue;
117
            }
118
119 5
            $components[$manifest->name] = midcom::get()->i18n->get_string($manifest->name, $manifest->name) . " ({$manifest->name})";
120
        }
121 5
        asort($components);
122
123 5
        $this->schema['fields'][$key] = [
124 5
            'title'       => $key,
125 5
            'storage'     => $key,
126 5
            'type'        => 'select',
127
            'type_config' => [
128 5
                'options' => $components,
129
            ],
130 5
            'widget'      => 'select',
131
        ];
132 5
    }
133
134 7
    protected function add_longtext_field(string $key)
135
    {
136 7
        parent::add_longtext_field($key);
137
138
        // Check the user preference and configuration
139 7
        if (   in_array($key, ['content', 'description'])
140 7
            && (    midgard_admin_asgard_plugin::get_preference('tinymce_enabled')
141 7
                || (   midgard_admin_asgard_plugin::get_preference('tinymce_enabled') !== '0'
142 7
                    && $this->_config->get('tinymce_enabled')))) {
143 7
            $this->schema['fields'][$key]['widget'] = 'tinymce';
144
        }
145
146 7
        if (   in_array($key, ['value', 'code'])
147 5
            && (    midgard_admin_asgard_plugin::get_preference('codemirror_enabled')
148 5
                || (   midgard_admin_asgard_plugin::get_preference('codemirror_enabled') !== '0'
149 7
                    && $this->_config->get('codemirror_enabled')))) {
150 5
            $this->schema['fields'][$key]['widget'] = 'codemirror';
151
        }
152 7
    }
153
154 8
    protected function add_linked_field(string $key)
155
    {
156 8
        parent::add_linked_field($key);
157
158 8
        $linked_type = $this->reflector->get_link_name($key);
159 8
        $type_label = midcom_helper_reflector::get($linked_type)->get_class_label();
160
161 8
        if ($key == 'up') {
162 8
            $field_label = sprintf($this->l10n->get('under %s'), $type_label);
163
        } else {
164 2
            $field_label = sprintf($this->l10n->get('%s (%s)'), $this->schema['fields'][$key]['title'], $type_label);
165
        }
166 8
        $this->schema['fields'][$key]['title'] = $field_label;
167
168 8
        $reflector = midcom_helper_reflector::get($linked_type);
169 8
        $this->schema['fields'][$key]['widget_config']['creation_mode_enabled'] = true;
170 8
        $this->schema['fields'][$key]['widget_config']['creation_handler'] = midcom_connection::get_url('self') . "__mfa/asgard/object/create/chooser/{$linked_type}/";
171 8
        $this->schema['fields'][$key]['widget_config']['creation_default_key'] = $reflector->get_title_property(new $linked_type);
172 8
    }
173
174 9
    private function _add_rcs_field()
175
    {
176 9
        $this->schema['fields']['_rcs_message'] = [
177 9
            'title'       => $this->l10n->get('revision comment'),
178
            'storage'     => null,
179 9
            'type'        => 'rcsmessage',
180 9
            'widget'      => 'text',
181
            'start_fieldset' => [
182 9
                'title' => $this->l10n->get('revision'),
183 9
                'css_group' => 'rcs',
184
            ],
185 9
            'end_fieldset' => '',
186
        ];
187 9
    }
188 2
    private function _add_copy_fields()
189
    {
190
        // Add switch for copying parameters
191 2
        $this->schema['fields']['parameters'] = [
192 2
            'title'       => $this->l10n->get('copy parameters'),
193
            'storage'     => null,
194 2
            'type'        => 'boolean',
195 2
            'widget'      => 'checkbox',
196
            'default'     => true,
197
        ];
198
199
        // Add switch for copying metadata
200 2
        $this->schema['fields']['metadata'] = [
201 2
            'title'       => $this->l10n->get('copy metadata'),
202
            'storage'     => null,
203 2
            'type'        => 'boolean',
204 2
            'widget'      => 'checkbox',
205
            'default'     => true,
206
        ];
207
208
        // Add switch for copying attachments
209 2
        $this->schema['fields']['attachments'] = [
210 2
            'title'       => $this->l10n->get('copy attachments'),
211
            'storage'     => null,
212 2
            'type'        => 'boolean',
213 2
            'widget'      => 'checkbox',
214
            'default'     => true,
215
        ];
216
217
        // Add switch for copying privileges
218 2
        $this->schema['fields']['privileges'] = [
219 2
            'title'       => $this->l10n->get('copy privileges'),
220
            'storage'     => null,
221 2
            'type'        => 'boolean',
222 2
            'widget'      => 'checkbox',
223
            'default'     => true,
224
        ];
225 2
    }
226
227 29
    private function _get_score(string $field) : int
228
    {
229 29
        $preferred_fields = $this->_config->get('object_preferred_fields');
230 29
        $timerange_fields = $this->_config->get('object_timerange_fields');
231 29
        $phone_fields = $this->_config->get('object_phone_fields');
232 29
        $address_fields = $this->_config->get('object_address_fields');
233 29
        $location_fields = $this->_config->get('object_location_fields');
234
235 29
        $score = 7;
236
237 29
        if ($this->reflector->get_midgard_type($field) == MGD_TYPE_LONGTEXT) {
238 14
            $score = 1;
239 28
        } elseif (in_array($field, $preferred_fields)) {
0 ignored issues
show
Bug introduced by
It seems like $preferred_fields can also be of type false; however, parameter $haystack of in_array() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

239
        } elseif (in_array($field, /** @scrutinizer ignore-type */ $preferred_fields)) {
Loading history...
240 14
            $score = 0;
241 25
        } elseif ($this->reflector->is_link($field)) {
242 11
            $score = 2;
243 23
        } elseif (in_array($field, $timerange_fields)) {
244 5
            $score = 3;
245 19
        } elseif (in_array($field, $phone_fields)) {
246 5
            $score = 4;
247 16
        } elseif (in_array($field, $address_fields)) {
248 5
            $score = 5;
249 12
        } elseif (in_array($field, $location_fields)) {
250
            $score = 6;
251
        }
252
253 29
        return $score;
254
    }
255
256 29
    public function sort_schema_fields(string $first, string $second)
257
    {
258 29
        $score1 = $this->_get_score($first);
259 29
        $score2 = $this->_get_score($second);
260 29
        if ($score1 < $score2) {
261 13
            return -1;
262
        }
263 23
        if ($score1 > $score2) {
264 17
            return 1;
265
        }
266 13
        if (   $score1 < 3
267 13
            || $score1 > 6) {
268 10
            return strnatcmp($first, $second);
269
        }
270
        switch ($score1) {
271 3
            case 3:
272 1
                $type = 'timerange';
273 1
                break;
274 2
            case 4:
275 1
                $type = 'phone';
276 1
                break;
277 1
            case 5:
278 1
                $type = 'address';
279 1
                break;
280
            case 6:
281
                $type = 'location';
282
                break;
283
        }
284 3
        $fields = $this->_config->get('object_' . $type . '_fields');
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $type does not seem to be defined for all execution paths leading up to this point.
Loading history...
285 3
        return array_search($first, $fields) <=> array_search($second, $fields);
0 ignored issues
show
Bug introduced by
It seems like $fields can also be of type false; however, parameter $haystack of array_search() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

285
        return array_search($first, /** @scrutinizer ignore-type */ $fields) <=> array_search($second, $fields);
Loading history...
286
    }
287
}
288