Completed
Branch master (e8947e)
by Andreas
15:09
created

midgard_admin_asgard_schemadb   F

Complexity

Total Complexity 88

Size/Duplication

Total Lines 734
Duplicated Lines 9.81 %

Coupling/Cohesion

Components 1
Dependencies 14

Importance

Changes 0
Metric Value
dl 72
loc 734
rs 1.3333
c 0
b 0
f 0
wmc 88
lcom 1
cbo 14

15 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 4 18 3
D create() 39 108 15
C _filter_schema_fields() 0 23 7
C _add_string_field() 0 70 8
A _add_rcs_field() 0 20 1
B _add_int_field() 0 39 5
C _add_longtext_field() 29 76 13
B _add_info_field_for_page() 0 29 1
B _add_name_field() 0 29 3
B _add_component_dropdown() 0 31 3
C _add_linked_field() 0 80 8
A _get_result_headers() 0 15 2
A _add_copy_fields() 0 58 1
C _get_score() 0 41 8
D sort_schema_fields() 0 35 10

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like midgard_admin_asgard_schemadb often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use midgard_admin_asgard_schemadb, and based on these observations, apply Extract Interface, too.

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
/**
10
 * Helper class to create a DM2 schema from an object via reflection
11
 *
12
 * @package midgard.admin.asgard
13
 */
14
class midgard_admin_asgard_schemadb
1 ignored issue
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
15
{
16
    /**
17
     * The object we're working with
18
     *
19
     * @var midcom_core_dbaobject
20
     */
21
    private $_object;
22
23
    /**
24
     * Component config for Asgard
25
     *
26
     * @var midcom_helper_configuration
27
     */
28
    private $_config;
29
30
    /**
31
     * The schema database in use, available only while a datamanager is loaded.
32
     *
33
     * @var array
34
     */
35
    private $_schemadb;
36
37
    /**
38
     * Midgard reflection property instance for the current object's class.
39
     *
40
     * @var midgard_reflection_property
41
     */
42
    private $_reflector;
43
44
    /**
45
     * Flag that controls if fields used for copying should be added
46
     *
47
     * @var boolean
48
     */
49
    public $add_copy_fields = false;
50
51
    public function __construct($object, $config, $type = null)
52
    {
53
        if ($type != null)
54
        {
55
            $this->_object = new $type();
56
        }
57
        else
58
        {
59
            $this->_object = $object;
60
        }
61 View Code Duplication
        if (!midcom::get()->dbclassloader->is_midcom_db_object($this->_object))
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
62
        {
63
            $this->_object = midcom::get()->dbfactory->convert_midgard_to_midcom($this->_object);
64
        }
65
        $this->_reflector = new midgard_reflection_property(midcom_helper_reflector::resolve_baseclass($this->_object));
66
        $this->_config = $config;
67
        $this->_l10n = midcom::get()->i18n->get_l10n('midgard.admin.asgard');
68
    }
69
70
    /**
71
     * Generates, loads and prepares the schema database.
72
     *
73
     * The operations are done on all available schemas within the DB.
74
     */
75
    public function create($include_fields)
76
    {
77
        $type = get_class($this->_object);
78
        $type_fields = $this->_object->get_properties();
79
80
        //This is an ugly little workaround for unittesting
81
        $template = midcom_helper_datamanager2_schema::load_database('file:/midgard/admin/asgard/config/schemadb_default.inc');
82
        $empty_db = clone $template['object'];
83
84
        $this->_schemadb = array('object' => $empty_db);
85
        //workaround end
86
87
        $component = midcom::get()->dbclassloader->get_component_for_class($type);
88
        if ($component)
89
        {
90
            $this->_schemadb['object']->l10n_schema = midcom::get()->i18n->get_l10n($component);
91
        }
92
93
        if (!empty($include_fields))
94
        {
95
            // Skip the fields that aren't requested, if inclusion list has been defined
96
            $type_fields = array_intersect($type_fields, (array) $include_fields);
97
        }
98
99
        $type_fields = array_filter($type_fields, array($this, '_filter_schema_fields'));
100
101
        if (extension_loaded('midgard'))
102
        {
103
            // Midgard1 returns properties in random order so we need to sort them heuristically
104
            usort($type_fields, array($this, 'sort_schema_fields'));
105
        }
106
107
        // Iterate through object properties
108
        foreach ($type_fields as $key)
109
        {
110
            // Linked fields should use chooser
111
            if ($this->_reflector->is_link($key))
112
            {
113
                $this->_add_linked_field($key);
114
                // Skip rest of processing
115
                continue;
116
            }
117
118
            $field_type = $this->_reflector->get_midgard_type($key);
119
            switch ($field_type)
120
            {
121
                case MGD_TYPE_GUID:
122
                case MGD_TYPE_STRING:
123
                    $this->_add_string_field($key, $type);
124
                    break;
125
                case MGD_TYPE_LONGTEXT:
126
                    $this->_add_longtext_field($key, $type);
127
                    break;
128
                case MGD_TYPE_INT:
129
                case MGD_TYPE_UINT:
130
                    $this->_add_int_field($key);
131
                    break;
132 View Code Duplication
                case MGD_TYPE_FLOAT:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
133
                    $this->_schemadb['object']->append_field
134
                    (
135
                        $key,
136
                        array
137
                        (
138
                            'title'       => $key,
139
                            'storage'     => $key,
140
                            'type'        => 'number',
141
                            'widget'      => 'text',
142
                        )
143
                    );
144
                    break;
145 View Code Duplication
                case MGD_TYPE_BOOLEAN:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
146
                    $this->_schemadb['object']->append_field
147
                    (
148
                        $key,
149
                        array
150
                        (
151
                            'title'       => $key,
152
                            'storage'     => $key,
153
                            'type'        => 'boolean',
154
                            'widget'      => 'checkbox',
155
                        )
156
                    );
157
                    break;
158 View Code Duplication
                case MGD_TYPE_TIMESTAMP:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
159
                    $this->_schemadb['object']->append_field
160
                    (
161
                        $key,
162
                        array
163
                        (
164
                            'title'       => $key,
165
                            'storage'     => $key,
166
                            'type' => 'date',
167
                            'widget' => 'jsdate',
168
                        )
169
                    );
170
                    break;
171
            }
172
        }
173
174
        $this->_add_rcs_field();
175
176
        if ($this->add_copy_fields)
177
        {
178
            $this->_add_copy_fields();
179
        }
180
181
        return $this->_schemadb;
182
    }
183
184
    private function _filter_schema_fields($key)
185
    {
186
        if (   $key == 'metadata'
187
            || in_array($key, $this->_config->get('object_skip_fields')))
188
        {
189
            return false;
190
        }
191
192
        // Only hosts have lang field that we will actually display
193
        if (   $key == 'lang'
194
            && !is_a($this->_object, 'midcom_db_host'))
195
        {
196
            return false;
197
        }
198
199
        // Skip topic symlink field because it is a special field not meant to be touched directly
200
        if (   $key == 'symlink'
201
            && is_a($this->_object, 'midcom_db_topic'))
202
        {
203
            return false;
204
        }
205
        return true;
206
    }
207
208
    private function _add_string_field($key, $type)
209
    {
210
        if (   $key == 'component'
211
            && $type == 'midcom_db_topic')
212
        {
213
            $this->_add_component_dropdown($key);
214
            return;
215
        }
216
        // Special page treatment
217
        if ($key === 'info')
218
        {
219
            if ($type === 'midcom_db_page')
220
            {
221
                $this->_add_info_field_for_page($key);
222
                return;
223
            }
224
225
            if ($type === 'midcom_db_pageelement')
226
            {
227
                $this->_schemadb['object']->append_field
228
                (
229
                    $key,
230
                    array
231
                    (
232
                        'title'       => $key,
233
                        'storage'     => $key,
234
                        'type'        => 'select',
235
                        'type_config' => array
236
                        (
237
                            'options' => array
238
                            (
239
                                '' => 'not inherited',
240
                                'inherit' => 'inherited',
241
                                ),
242
                            ),
243
                        'widget'      => 'select',
244
                        )
245
                    );
246
                return;
247
            }
248
        }
249
250
        // 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)
251
        if (midcom::get()->dbfactory->is_a($this->_object, $type))
252
        {
253
            $name_obj = $this->_object;
254
        }
255
        else
256
        {
257
            $name_obj = new $type();
258
        }
259
260
        if ($key === midcom_helper_reflector::get_name_property($name_obj))
261
        {
262
            $this->_add_name_field($key, $name_obj);
263
            return;
264
        }
265
266
        $this->_schemadb['object']->append_field
267
        (
268
            $key,
269
            array
270
            (
271
                'title'       => $key,
272
                'storage'     => $key,
273
                'type'        => 'text',
274
                'widget'      => 'text',
275
            )
276
        );
277
    }
278
279
    private function _add_rcs_field()
280
    {
281
        $this->_schemadb['object']->append_field
282
        (
283
            '_rcs_message',
284
            array
285
            (
286
                'title'       => $this->_l10n->get('revision comment'),
287
                'storage'     => '_rcs_message',
288
                'type'        => 'text',
289
                'widget'      => 'text',
290
                'start_fieldset' => array
291
                (
292
                    'title' => $this->_l10n->get('revision'),
293
                    'css_group' => 'rcs',
294
                ),
295
                'end_fieldset' => '',
296
            )
297
        );
298
    }
299
300
    private function _add_int_field($key)
301
    {
302
        if (   $key == 'start'
303
            || $key == 'end'
304
            || $key == 'added'
305
            || $key == 'date')
306
        {
307
            // We can safely assume that INT fields called start and end store unixtimes
308
            $this->_schemadb['object']->append_field
309
            (
310
                $key,
311
                array
312
                (
313
                    'title'       => $key,
314
                    'storage'     => $key,
315
                    'type' => 'date',
316
                    'type_config' => array
317
                    (
318
                        'storage_type' => 'UNIXTIME'
319
                        ),
320
                    'widget' => 'jsdate',
321
                )
322
            );
323
        }
324
        else
325
        {
326
            $this->_schemadb['object']->append_field
327
            (
328
                $key,
329
                array
330
                (
331
                    'title'       => $key,
332
                    'storage'     => $key,
333
                    'type'        => 'number',
334
                    'widget'      => 'text',
335
                )
336
            );
337
        }
338
    }
339
340
    private function _add_longtext_field($key, $type)
341
    {
342
        // Figure out nice size for the editing field
343
344
        $output_mode = '';
345
        $widget = 'textarea';
346
        $dm_type = 'text';
347
348
        // Workaround for the content field of pages
349
        $adjusted_key = $key;
350
        if (   $type == 'midcom_db_page'
351
            && $key == 'content')
352
        {
353
            $adjusted_key = 'code';
354
        }
355
356
        switch ($adjusted_key)
357
        {
358
            case 'content':
359 View Code Duplication
            case 'description':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
360
                $height = 30;
361
362
                // Check the user preference and configuration
363
                if (   midgard_admin_asgard_plugin::get_preference('tinymce_enabled')
364
                    || (   midgard_admin_asgard_plugin::get_preference('tinymce_enabled') !== '0'
365
                        && $this->_config->get('tinymce_enabled')))
366
                {
367
                    $widget = 'tinymce';
368
                }
369
                $output_mode = 'html';
370
371
                break;
372
            case 'value':
373 View Code Duplication
            case 'code':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
374
                // These are typical "large" fields
375
                $height = 30;
376
377
                // Check the user preference and configuration
378
                if (   midgard_admin_asgard_plugin::get_preference('codemirror_enabled')
379
                    || (   midgard_admin_asgard_plugin::get_preference('codemirror_enabled') !== '0'
380
                        && $this->_config->get('codemirror_enabled')))
381
                {
382
                    $widget = 'codemirror';
383
                }
384
385
                $dm_type = 'php';
386
                $output_mode = 'code';
387
388
                break;
389
390
            default:
391
                $height = 6;
392
                break;
393
        }
394
395
        $this->_schemadb['object']->append_field
396
        (
397
            $key,
398
            array
399
            (
400
                'title'       => $key,
401
                'storage'     => $key,
402
                'type'        => $dm_type,
403
                'type_config' => Array
404
                (
405
                    'output_mode' => $output_mode,
406
                ),
407
                'widget'      => $widget,
408
                'widget_config' => Array
409
                (
410
                    'height' => $height,
411
                    'width' => '100%',
412
                ),
413
            )
414
        );
415
    }
416
417
    private function _add_info_field_for_page($key)
418
    {
419
        $this->_schemadb['object']->append_field
420
        (
421
            $key,
422
            array
423
            (
424
                'title'       => $key,
425
                'storage'     => $key,
426
                'type'        => 'select',
427
                'type_config' => array
428
                (
429
                    'allow_multiple' => true,
430
                    'multiple_separator' => ',',
431
                    'multiple_storagemode' => 'imploded',
432
                    'options' => array
433
                    (
434
                        'auth'        => 'require authentication',
435
                        'active'      => 'active url parsing',
436
                        ),
437
                    ),
438
                'widget'      => 'select',
439
                'widget_config' => array
440
                (
441
                    'height' => 2,
442
                    ),
443
                )
444
        );
445
    }
446
447
    private function _add_name_field($key, $name_obj)
448
    {
449
        $type_urlname_config = array();
450
        $allow_unclean_name_types = $this->_config->get('allow_unclean_names_for');
451
        foreach ($allow_unclean_name_types as $allow_unclean_name_types_type)
452
        {
453
            if (midcom::get()->dbfactory->is_a($name_obj, $allow_unclean_name_types_type))
454
            {
455
                $type_urlname_config['allow_unclean'] = true;
456
                break;
457
            }
458
        }
459
460
        // Enable generating the name from the title property
461
        $type_urlname_config['title_field'] = midcom_helper_reflector::get_title_property($name_obj);
462
463
        $this->_schemadb['object']->append_field
464
        (
465
            $key,
466
            array
467
            (
468
                'title'       => $key,
469
                'storage'     => $key,
470
                'type'        => 'urlname',
471
                'type_config' => $type_urlname_config,
472
                'widget'      => 'text',
473
                )
474
        );
475
    }
476
477
    private function _add_component_dropdown($key)
478
    {
479
        $components = array('' => '');
480
        foreach (midcom::get()->componentloader->manifests as $manifest)
481
        {
482
            // Skip purecode components
483
            if ($manifest->purecode)
484
            {
485
                continue;
486
            }
487
488
            $components[$manifest->name] = midcom::get()->i18n->get_string($manifest->name, $manifest->name) . " ({$manifest->name})";
489
        }
490
        asort($components);
491
492
        $this->_schemadb['object']->append_field
493
        (
494
            $key,
495
            array
496
            (
497
                'title'       => $key,
498
                'storage'     => $key,
499
                'type'        => 'select',
500
                'type_config' => array
501
                (
502
                    'options' => $components,
503
                ),
504
                'widget'      => 'midcom_admin_folder_selectcomponent',
505
            )
506
        );
507
    }
508
509
    private function _add_linked_field($key)
510
    {
511
        $linked_type = $this->_reflector->get_link_name($key);
512
        $linked_type_reflector = midcom_helper_reflector::get($linked_type);
513
        $field_type = $this->_reflector->get_midgard_type($key);
514
515
        if ($key == 'up')
516
        {
517
            $field_label = sprintf($this->_l10n->get('under %s'), midgard_admin_asgard_plugin::get_type_label($linked_type));
518
        }
519
        else
520
        {
521
            $type_label = midgard_admin_asgard_plugin::get_type_label($linked_type);
522
            if (substr($type_label, 0, strlen($key)) == $key)
523
            {
524
                // Handle abbreviations like "lang" for "language"
525
                $field_label = $type_label;
526
            }
527
            else if ($key == $type_label)
528
            {
529
                $field_label = $key;
530
            }
531
            else
532
            {
533
                $ref = midcom_helper_reflector::get($this->_object);
534
                $component_l10n = $ref->get_component_l10n();
535
                $field_label = sprintf($this->_l10n->get('%s (%s)'), $component_l10n->get($key), $type_label);
536
            }
537
        }
538
539
        // Get the chooser widgets
540
        switch ($field_type)
541
        {
542
            case MGD_TYPE_UINT:
543
            case MGD_TYPE_STRING:
544
            case MGD_TYPE_GUID:
545
                $class = midcom::get()->dbclassloader->get_midcom_class_name_for_mgdschema_object($linked_type);
546
                if (! $class)
547
                {
548
                    break;
549
                }
550
                $component = midcom::get()->dbclassloader->get_component_for_class($linked_type);
551
                $searchfields = $linked_type_reflector->get_search_properties();
552
                $searchfields[] = 'guid';
553
                $this->_schemadb['object']->append_field
554
                (
555
                    $key,
556
                    array
557
                    (
558
                        'title'       => $field_label,
559
                        'storage'     => $key,
560
                        'type'        => 'select',
561
                        'type_config' => array
562
                        (
563
                            'require_corresponding_option' => false,
564
                            'options' => array(),
565
                            'allow_other' => true,
566
                            'allow_multiple' => false,
567
                        ),
568
                        'widget' => 'autocomplete',
569
                        'widget_config' => array
570
                        (
571
                            'class' => $class,
572
                            'component' => $component,
573
                            'titlefield' => $linked_type_reflector->get_label_property(),
574
                            'id_field' => $this->_reflector->get_link_target($key),
575
                            'searchfields' => $searchfields,
576
                            'result_headers' => $this->_get_result_headers($linked_type_reflector),
577
                            'orders' => array(),
578
                            'creation_mode_enabled' => true,
579
                            'creation_handler' => midcom_connection::get_url('self') . "__mfa/asgard/object/create/chooser/{$linked_type}/",
580
                            'creation_default_key' => $linked_type_reflector->get_title_property(new $linked_type),
581
                            'categorize_by_parent_label' => true,
582
                            'get_label_for' => $linked_type_reflector->get_label_property(),
583
                            ),
584
                        )
585
                    );
586
                break;
587
        }
588
    }
589
590
    /**
591
     * Get headers to be used with chooser
592
     *
593
     * @return array
594
     */
595
    private function _get_result_headers($linked_type_reflector)
596
    {
597
        $headers = array();
598
        $properties = $linked_type_reflector->get_search_properties();
599
        $l10n = $linked_type_reflector->get_component_l10n();
600
        foreach ($properties as $property)
601
        {
602
            $headers[] = array
603
            (
604
                'name' => $property,
605
                'title' => ucfirst($l10n->get($property)),
606
            );
607
        }
608
        return $headers;
609
    }
610
611
    private function _add_copy_fields()
612
    {
613
        // Add switch for copying parameters
614
        $this->_schemadb['object']->append_field
615
        (
616
            'parameters',
617
            array
618
            (
619
                'title'       => $this->_l10n->get('copy parameters'),
620
                'storage'     => null,
621
                'type'        => 'boolean',
622
                'widget'      => 'checkbox',
623
                'default'     => 1,
624
            )
625
        );
626
627
        // Add switch for copying metadata
628
        $this->_schemadb['object']->append_field
629
        (
630
            'metadata',
631
            array
632
            (
633
                'title'       => $this->_l10n->get('copy metadata'),
634
                'storage'     => null,
635
                'type'        => 'boolean',
636
                'widget'      => 'checkbox',
637
                'default'     => 1,
638
            )
639
        );
640
641
        // Add switch for copying attachments
642
        $this->_schemadb['object']->append_field
643
        (
644
            'attachments',
645
            array
646
            (
647
                'title'       => $this->_l10n->get('copy attachments'),
648
                'storage'     => null,
649
                'type'        => 'boolean',
650
                'widget'      => 'checkbox',
651
                'default'     => 1,
652
            )
653
        );
654
655
        // Add switch for copying privileges
656
        $this->_schemadb['object']->append_field
657
        (
658
            'privileges',
659
            array
660
            (
661
                'title'       => $this->_l10n->get('copy privileges'),
662
                'storage'     => null,
663
                'type'        => 'boolean',
664
                'widget'      => 'checkbox',
665
                'default'     => 1,
666
            )
667
        );
668
    }
669
670
    private function _get_score($field)
671
    {
672
        $preferred_fields = $this->_config->get('object_preferred_fields');
673
        $timerange_fields = $this->_config->get('object_timerange_fields');
674
        $phone_fields = $this->_config->get('object_phone_fields');
675
        $address_fields = $this->_config->get('object_address_fields');
676
        $location_fields = $this->_config->get('object_location_fields');
677
678
        $score = 7;
679
680
        if ($this->_reflector->get_midgard_type($field) == MGD_TYPE_LONGTEXT)
681
        {
682
            $score = 1;
683
        }
684
        else if (in_array($field, $preferred_fields))
685
        {
686
            $score = 0;
687
        }
688
        else if ($this->_reflector->is_link($field))
689
        {
690
            $score = 2;
691
        }
692
        else if (in_array($field, $timerange_fields))
693
        {
694
            $score = 3;
695
        }
696
        else if (in_array($field, $phone_fields))
697
        {
698
            $score = 4;
699
        }
700
        else if (in_array($field, $address_fields))
701
        {
702
            $score = 5;
703
        }
704
        else if (in_array($field, $location_fields))
705
        {
706
            $score = 6;
707
        }
708
709
        return $score;
710
    }
711
712
    public function sort_schema_fields($first, $second)
713
    {
714
        $score1 = $this->_get_score($first);
715
        $score2 = $this->_get_score($second);
716
        if ($score1 < $score2)
717
        {
718
            return -1;
719
        }
720
        if ($score1 > $score2)
721
        {
722
            return 1;
723
        }
724
        if (   $score1 < 3
725
            || $score1 > 6)
726
        {
727
            return strnatcmp($first, $second);
728
        }
729
        switch ($score1)
730
        {
731
            case 3:
732
                $type = 'timerange';
733
                break;
734
            case 4:
735
                $type = 'phone';
736
                break;
737
            case 5:
738
                $type = 'address';
739
                break;
740
            case 6:
741
                $type = 'location';
742
                break;
743
        }
744
        $fields = $this->_config->get('object_' . $type . '_fields');
0 ignored issues
show
Bug introduced by
The variable $type does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
745
        return (array_search($first, $fields) < array_search($second, $fields)) ? -1 : 1;
746
    }
747
}
748