Passed
Push — master ( 7a49a3...f0ede1 )
by Andreas
22:15
created

midgard_admin_asgard_schemadb::_add_copy_fields()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 36
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 28
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 24
nc 1
nop 0
dl 0
loc 36
ccs 28
cts 28
cp 1
crap 1
rs 9.536
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
    private midcom_helper_configuration $_config;
19
20
    private midcom_services_i18n_l10n $l10n;
21
22
    public bool $add_copy_fields = false;
23
24 31
    public function __construct(midcom_core_dbaobject $object, midcom_helper_configuration $config)
25
    {
26 31
        parent::__construct($object);
27 31
        $this->_config = $config;
28 31
        $this->l10n = midcom::get()->i18n->get_l10n('midgard.admin.asgard');
29
    }
30
31
    /**
32
     * Generates, loads and prepares the schema database.
33
     *
34
     * The operations are done on all available schemas within the DB.
35
     */
36 9
    protected function process_type(string $type, array $type_fields)
37
    {
38 9
        usort($type_fields, [$this, 'sort_schema_fields']);
39
40 9
        parent::process_type($type, $type_fields);
41
42 9
        $this->_add_rcs_field();
43
44 9
        if ($this->add_copy_fields) {
45 2
            $this->_add_copy_fields();
46
        }
47 9
        if (empty($this->schema['l10n_db'])) {
48
            $this->schema['l10n_db'] = 'midgard.admin.asgard';
49
        }
50 9
        $this->schema['templates']['view'] = \midcom\datamanager\template\view::class;
51 9
        $this->schema['templates']['form'] = \midcom\datamanager\template\form::class;
52
    }
53
54 7
    protected function add_string_field(string $key, string $type)
55
    {
56 7
        if (   $key == 'component'
57 7
            && $type == midcom_db_topic::class) {
58 5
            $this->_add_component_dropdown($key);
59 5
            return;
60
        }
61
62
        // 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)
63 7
        if ($this->object instanceof $type) {
64 7
            $name_obj = $this->object;
65
        } else {
66
            $name_obj = new $type();
67
        }
68
69 7
        if ($key === midcom_helper_reflector::get_name_property($name_obj)) {
70 7
            $this->_add_name_field($key, $name_obj);
71 7
            return;
72
        }
73 7
        parent::add_string_field($key, $type);
74
    }
75
76 7
    private function _add_name_field(string $key, midcom_core_dbaobject $name_obj)
77
    {
78 7
        $type_urlname_config = [];
79 7
        $allow_unclean_name_types = $this->_config->get_array('allow_unclean_names_for');
80 7
        foreach ($allow_unclean_name_types as $allow_unclean_name_types_type) {
81 7
            if ($name_obj->__object instanceof $allow_unclean_name_types_type) {
82
                $type_urlname_config['allow_unclean'] = true;
83
                break;
84
            }
85
        }
86
87
        // Enable generating the name from the title property
88 7
        if ($title_field = midcom_helper_reflector::get_title_property($name_obj)) {
89 7
            $type_urlname_config['title_field'] = $title_field;
90
        }
91
92 7
        $this->schema['fields'][$key] = [
93 7
            'title'       => $key,
94 7
            'storage'     => $key,
95 7
            'type'        => 'urlname',
96 7
            'type_config' => $type_urlname_config,
97 7
            'widget'      => 'text',
98 7
        ];
99
    }
100
101 5
    private function _add_component_dropdown(string $key)
102
    {
103 5
        $components = ['' => ''];
104 5
        foreach (midcom::get()->componentloader->get_manifests() as $manifest) {
105
            // Skip purecode components
106 5
            if (!$manifest->purecode) {
107 5
                $components[$manifest->name] = $manifest->get_name_translated() . " ({$manifest->name})";
108
            }
109
        }
110 5
        asort($components);
111
112 5
        $this->schema['fields'][$key] = [
113 5
            'title'       => $key,
114 5
            'storage'     => $key,
115 5
            'type'        => 'select',
116 5
            'type_config' => [
117 5
                'options' => $components,
118 5
            ],
119 5
            'widget'      => 'select',
120 5
        ];
121
    }
122
123 7
    protected function add_longtext_field(string $key)
124
    {
125 7
        parent::add_longtext_field($key);
126
127
        // Check the user preference and configuration
128 7
        if (   in_array($key, ['content', 'description'])
129 7
            && midgard_admin_asgard_plugin::get_preference('tinymce_enabled')) {
130
            $this->schema['fields'][$key]['widget'] = 'tinymce';
131
        }
132
133 7
        if (   in_array($key, ['value', 'code'])
134 7
            && midgard_admin_asgard_plugin::get_preference('codemirror_enabled')) {
135
            $this->schema['fields'][$key]['widget'] = 'codemirror';
136
        }
137
    }
138
139 8
    protected function add_linked_field(string $key)
140
    {
141 8
        parent::add_linked_field($key);
142
143 8
        $linked_type = $this->reflector->get_link_name($key);
144 8
        $type_label = midcom_helper_reflector::get($linked_type)->get_class_label();
145
146 8
        if ($key == 'up') {
147 8
            $field_label = sprintf($this->l10n->get('under %s'), $type_label);
148
        } else {
149 2
            $field_label = sprintf($this->l10n->get('%s (%s)'), $this->schema['fields'][$key]['title'], $type_label);
150
        }
151 8
        $this->schema['fields'][$key]['title'] = $field_label;
152
153 8
        $this->schema['fields'][$key]['widget_config']['creation_mode_enabled'] = true;
154 8
        $this->schema['fields'][$key]['widget_config']['creation_handler'] = midcom_connection::get_url('self') . "__mfa/asgard/object/create/chooser/{$linked_type}/";
155 8
        $this->schema['fields'][$key]['widget_config']['creation_default_key'] = midcom_helper_reflector::get_title_property(new $linked_type);
156
    }
157
158 9
    private function _add_rcs_field()
159
    {
160 9
        $this->schema['fields']['_rcs_message'] = [
161 9
            'title'       => $this->l10n->get('revision comment'),
162 9
            'storage'     => null,
163 9
            'type'        => 'rcsmessage',
164 9
            'widget'      => 'text',
165 9
            'start_fieldset' => [
166 9
                'title' => $this->l10n->get('revision'),
167 9
                'css_group' => 'rcs',
168 9
            ],
169 9
            'end_fieldset' => '',
170 9
        ];
171
    }
172 2
    private function _add_copy_fields()
173
    {
174
        // Add switch for copying parameters
175 2
        $this->schema['fields']['parameters'] = [
176 2
            'title'       => $this->l10n->get('copy parameters'),
177 2
            'storage'     => null,
178 2
            'type'        => 'boolean',
179 2
            'widget'      => 'checkbox',
180 2
            'default'     => true,
181 2
        ];
182
183
        // Add switch for copying metadata
184 2
        $this->schema['fields']['metadata'] = [
185 2
            'title'       => $this->l10n->get('copy metadata'),
186 2
            'storage'     => null,
187 2
            'type'        => 'boolean',
188 2
            'widget'      => 'checkbox',
189 2
            'default'     => true,
190 2
        ];
191
192
        // Add switch for copying attachments
193 2
        $this->schema['fields']['attachments'] = [
194 2
            'title'       => $this->l10n->get('copy attachments'),
195 2
            'storage'     => null,
196 2
            'type'        => 'boolean',
197 2
            'widget'      => 'checkbox',
198 2
            'default'     => true,
199 2
        ];
200
201
        // Add switch for copying privileges
202 2
        $this->schema['fields']['privileges'] = [
203 2
            'title'       => $this->l10n->get('copy privileges'),
204 2
            'storage'     => null,
205 2
            'type'        => 'boolean',
206 2
            'widget'      => 'checkbox',
207 2
            'default'     => true,
208 2
        ];
209
    }
210
211 29
    private function _get_score(string $field) : int
212
    {
213 29
        $preferred_fields = $this->_config->get_array('object_preferred_fields');
214 29
        $timerange_fields = $this->_config->get_array('object_timerange_fields');
215 29
        $phone_fields = $this->_config->get_array('object_phone_fields');
216 29
        $address_fields = $this->_config->get_array('object_address_fields');
217 29
        $location_fields = $this->_config->get_array('object_location_fields');
218
219 29
        $score = 7;
220
221 29
        if ($this->reflector->get_midgard_type($field) == MGD_TYPE_LONGTEXT) {
222 14
            $score = 1;
223 28
        } elseif (in_array($field, $preferred_fields)) {
224 14
            $score = 0;
225 25
        } elseif ($this->reflector->is_link($field)) {
226 11
            $score = 2;
227 23
        } elseif (in_array($field, $timerange_fields)) {
228 5
            $score = 3;
229 19
        } elseif (in_array($field, $phone_fields)) {
230 5
            $score = 4;
231 16
        } elseif (in_array($field, $address_fields)) {
232 5
            $score = 5;
233 12
        } elseif (in_array($field, $location_fields)) {
234
            $score = 6;
235
        }
236
237 29
        return $score;
238
    }
239
240 29
    public function sort_schema_fields(string $first, string $second) : int
241
    {
242 29
        $score1 = $this->_get_score($first);
243 29
        $score2 = $this->_get_score($second);
244 29
        if ($score1 < $score2) {
245 13
            return -1;
246
        }
247 23
        if ($score1 > $score2) {
248 17
            return 1;
249
        }
250 13
        if (   $score1 < 3
251 13
            || $score1 > 6) {
252 10
            return strnatcmp($first, $second);
253
        }
254
        switch ($score1) {
255 3
            case 3:
256 1
                $type = 'timerange';
257 1
                break;
258 2
            case 4:
259 1
                $type = 'phone';
260 1
                break;
261 1
            case 5:
262 1
                $type = 'address';
263 1
                break;
264
            case 6:
265
                $type = 'location';
266
                break;
267
        }
268 3
        $fields = $this->_config->get_array('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...
269 3
        return array_search($first, $fields) <=> array_search($second, $fields);
270
    }
271
}
272