Passed
Push — master ( ac2cf9...6ee9d0 )
by Andreas
24:39
created

add_longtext_field()   A

Complexity

Conditions 5
Paths 4

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 5.3906

Importance

Changes 0
Metric Value
cc 5
eloc 7
nc 4
nop 1
dl 0
loc 13
ccs 6
cts 8
cp 0.75
crap 5.3906
rs 9.6111
c 0
b 0
f 0
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
                $components[$manifest->name] = $manifest->get_name_translated() . " ({$manifest->name})";
117
            }
118
        }
119 5
        asort($components);
120
121 5
        $this->schema['fields'][$key] = [
122 5
            'title'       => $key,
123 5
            'storage'     => $key,
124 5
            'type'        => 'select',
125
            'type_config' => [
126 5
                'options' => $components,
127
            ],
128 5
            'widget'      => 'select',
129
        ];
130 5
    }
131
132 7
    protected function add_longtext_field(string $key)
133
    {
134 7
        parent::add_longtext_field($key);
135
136
        // Check the user preference and configuration
137 7
        if (   in_array($key, ['content', 'description'])
138 7
            && midgard_admin_asgard_plugin::get_preference('tinymce_enabled')) {
139
            $this->schema['fields'][$key]['widget'] = 'tinymce';
140
        }
141
142 7
        if (   in_array($key, ['value', 'code'])
143 7
            && midgard_admin_asgard_plugin::get_preference('codemirror_enabled')) {
144
            $this->schema['fields'][$key]['widget'] = 'codemirror';
145
        }
146 7
    }
147
148 8
    protected function add_linked_field(string $key)
149
    {
150 8
        parent::add_linked_field($key);
151
152 8
        $linked_type = $this->reflector->get_link_name($key);
153 8
        $type_label = midcom_helper_reflector::get($linked_type)->get_class_label();
154
155 8
        if ($key == 'up') {
156 8
            $field_label = sprintf($this->l10n->get('under %s'), $type_label);
157
        } else {
158 2
            $field_label = sprintf($this->l10n->get('%s (%s)'), $this->schema['fields'][$key]['title'], $type_label);
159
        }
160 8
        $this->schema['fields'][$key]['title'] = $field_label;
161
162 8
        $reflector = midcom_helper_reflector::get($linked_type);
163 8
        $this->schema['fields'][$key]['widget_config']['creation_mode_enabled'] = true;
164 8
        $this->schema['fields'][$key]['widget_config']['creation_handler'] = midcom_connection::get_url('self') . "__mfa/asgard/object/create/chooser/{$linked_type}/";
165 8
        $this->schema['fields'][$key]['widget_config']['creation_default_key'] = $reflector->get_title_property(new $linked_type);
166 8
    }
167
168 9
    private function _add_rcs_field()
169
    {
170 9
        $this->schema['fields']['_rcs_message'] = [
171 9
            'title'       => $this->l10n->get('revision comment'),
172
            'storage'     => null,
173 9
            'type'        => 'rcsmessage',
174 9
            'widget'      => 'text',
175
            'start_fieldset' => [
176 9
                'title' => $this->l10n->get('revision'),
177 9
                'css_group' => 'rcs',
178
            ],
179 9
            'end_fieldset' => '',
180
        ];
181 9
    }
182 2
    private function _add_copy_fields()
183
    {
184
        // Add switch for copying parameters
185 2
        $this->schema['fields']['parameters'] = [
186 2
            'title'       => $this->l10n->get('copy parameters'),
187
            'storage'     => null,
188 2
            'type'        => 'boolean',
189 2
            'widget'      => 'checkbox',
190
            'default'     => true,
191
        ];
192
193
        // Add switch for copying metadata
194 2
        $this->schema['fields']['metadata'] = [
195 2
            'title'       => $this->l10n->get('copy metadata'),
196
            'storage'     => null,
197 2
            'type'        => 'boolean',
198 2
            'widget'      => 'checkbox',
199
            'default'     => true,
200
        ];
201
202
        // Add switch for copying attachments
203 2
        $this->schema['fields']['attachments'] = [
204 2
            'title'       => $this->l10n->get('copy attachments'),
205
            'storage'     => null,
206 2
            'type'        => 'boolean',
207 2
            'widget'      => 'checkbox',
208
            'default'     => true,
209
        ];
210
211
        // Add switch for copying privileges
212 2
        $this->schema['fields']['privileges'] = [
213 2
            'title'       => $this->l10n->get('copy privileges'),
214
            'storage'     => null,
215 2
            'type'        => 'boolean',
216 2
            'widget'      => 'checkbox',
217
            'default'     => true,
218
        ];
219 2
    }
220
221 29
    private function _get_score(string $field) : int
222
    {
223 29
        $preferred_fields = $this->_config->get('object_preferred_fields');
224 29
        $timerange_fields = $this->_config->get('object_timerange_fields');
225 29
        $phone_fields = $this->_config->get('object_phone_fields');
226 29
        $address_fields = $this->_config->get('object_address_fields');
227 29
        $location_fields = $this->_config->get('object_location_fields');
228
229 29
        $score = 7;
230
231 29
        if ($this->reflector->get_midgard_type($field) == MGD_TYPE_LONGTEXT) {
232 14
            $score = 1;
233 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

233
        } elseif (in_array($field, /** @scrutinizer ignore-type */ $preferred_fields)) {
Loading history...
234 14
            $score = 0;
235 25
        } elseif ($this->reflector->is_link($field)) {
236 11
            $score = 2;
237 23
        } elseif (in_array($field, $timerange_fields)) {
238 5
            $score = 3;
239 19
        } elseif (in_array($field, $phone_fields)) {
240 5
            $score = 4;
241 16
        } elseif (in_array($field, $address_fields)) {
242 5
            $score = 5;
243 12
        } elseif (in_array($field, $location_fields)) {
244
            $score = 6;
245
        }
246
247 29
        return $score;
248
    }
249
250 29
    public function sort_schema_fields(string $first, string $second)
251
    {
252 29
        $score1 = $this->_get_score($first);
253 29
        $score2 = $this->_get_score($second);
254 29
        if ($score1 < $score2) {
255 13
            return -1;
256
        }
257 23
        if ($score1 > $score2) {
258 17
            return 1;
259
        }
260 13
        if (   $score1 < 3
261 13
            || $score1 > 6) {
262 10
            return strnatcmp($first, $second);
263
        }
264
        switch ($score1) {
265 3
            case 3:
266 1
                $type = 'timerange';
267 1
                break;
268 2
            case 4:
269 1
                $type = 'phone';
270 1
                break;
271 1
            case 5:
272 1
                $type = 'address';
273 1
                break;
274
            case 6:
275
                $type = 'location';
276
                break;
277
        }
278 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...
279 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

279
        return array_search($first, /** @scrutinizer ignore-type */ $fields) <=> array_search($second, $fields);
Loading history...
280
    }
281
}
282