Completed
Push — master ( 04904b...813d0b )
by H
02:49
created

Classification   B

Complexity

Total Complexity 42

Size/Duplication

Total Lines 206
Duplicated Lines 2.91 %

Coupling/Cohesion

Components 1
Dependencies 0

Importance

Changes 3
Bugs 0 Features 0
Metric Value
wmc 42
c 3
b 0
f 0
lcom 1
cbo 0
dl 6
loc 206
rs 8.295

16 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 9 2
A getArray() 0 4 1
A getJson() 0 4 1
A getByCode() 0 4 2
A getSelectArray() 0 15 4
A getSelectWidget() 0 20 4
A getSelectWidget4() 0 17 3
A fillWidget4SelectOptions() 0 16 4
C getSelectArray4() 6 47 8
A simplifyItemDataArray() 0 14 3
A getByName() 0 8 3
A getByTopCategory() 0 4 1
A getByFirstCategory() 0 4 1
A getBySecondCategory() 0 4 1
A getByThirdCategory() 0 4 1
A getByCategory() 0 10 3

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 Classification 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 Classification, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Wispiring\ChinaEconomyClassification;
4
5
class Classification
6
{
7
    const STANDARD = 'GB/4754';
8
    private $dataSource;
9
    private $data;
10
11
    public function __construct($dataSource = null)
12
    {
13
        if (null === $dataSource) {
14
            $this->dataSource = 'Y2011';
15
        }
16
        $className = '\Wispiring\ChinaEconomyClassification\Data\\'.$this->dataSource;
17
        $this->data = new $className();
18
        $this->data = $this->data->get();
19
    }
20
21
    public function getArray()
22
    {
23
        return $this->data;
24
    }
25
26
    public function getJson()
27
    {
28
        return json_encode($this->data);
29
    }
30
31
    public function getByCode($code)
32
    {
33
        return isset($this->data[$code]) ? $this->data[$code] : null;
34
    }
35
36
    public function getSelectArray()
37
    {
38
        $o = [];
39
        foreach ($this->data as $key => $value) {
40
            if (strlen($value['code']) !== 4) {
41
                continue;
42
            }
43
            $groupLabel = $value['top_category'].' '.$this->data[$value['top_category']]['name'];
44
            if (!isset($o[$groupLabel])) {
45
                $o[$groupLabel] = [];
46
            }
47
            $o[$groupLabel][$value['code']] = $value['code'].' '.$value['name'];
48
        }
49
        return $o;
50
    }
51
52
    public function getSelectWidget($name, $selectedValue = null)
53
    {
54
        $data = $this->getSelectArray();
55
56
        $o = '<select name="'.$name.'">';
57
        foreach ($data as $label => $d) {
58
            $o .= '<optgroup label="'.$label.'">';
59
            foreach ($d as $value => $name) {
60
                $o .= '<option value="'.$value.'"';
61
                if ($selectedValue == $value) {
62
                    $o .= ' selected="selected"';
63
                }
64
                $o .= '>'.$name.'</option>';
65
            }
66
            $o .= '</optgroup>';
67
        }
68
        $o .= '</select>';
69
70
        return $o;
71
    }
72
73
    public function getSelectWidget4($name, $selectedValue = null)
74
    {
75
        $o = '';
76
        $data = $this->getSelectArray4($selectedValue);
77
78
        foreach ($data as $index => $items) {
79
            $o .= '<select';
80
            if ($index == 3) {
81
                $o .= ' name="'.$name.'"';
82
            }
83
            $o .= '><option></option>';
84
            $o .= $this->fillWidget4SelectOptions($items);
85
            $o .= '</select>';
86
        }
87
88
        return '<div class="wispiring-cec-combo">'.$o.'</div>';
89
    }
90
91
    private function fillWidget4SelectOptions($items)
92
    {
93
        $o = '';
94
        foreach ($items as $d) {
95
            $o .= '<option value="'.$d['code'].'"';
96
            if (isset($d['parent'])) {
97
                $o .= ' data-parent="'.$d['parent'].'"';
98
            }
99
            if ($d['selected']) {
100
                $o .= ' selected="selected"';
101
            }
102
            $o .= '>'.$d['code'].' '.$d['name'].'</option>';
103
        }
104
105
        return $o;
106
    }
107
108
    public function getSelectArray4($selectedValue = null)
109
    {
110
        $o = [[],[],[],[]];
111
112
        if ($selectedValue) {
113
            $selected = $this->data[$selectedValue];
114
        } else {
115
            $selected = [
116
                'code' => null,
117
                'top_category' => null,
118
                'first_category' => null,
119
                'second_category' => null,
120
            ];
121
        }
122
123
        foreach ($this->data as $key => $value) {
124
            $keyLen = strlen($key);
125
            switch ($keyLen) {
126
                case 1:
127
                    $o[0][$key]= $this->simplifyItemDataArray($value, null, $selected['top_category']);
128
                    break;
129 View Code Duplication
                case 2:
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...
130
                    $o[1][$key]= $this->simplifyItemDataArray($value, 'top_category', $selected['first_category']);
131
                    break;
132 View Code Duplication
                case 3:
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
                    $o[2][$key]= $this->simplifyItemDataArray($value, 'first_category', $selected['second_category']);
134
                    break;
135
                case 4:
136
                    $o[3][$key]= $this->simplifyItemDataArray($value, 'second_category', $selected['code']);
137
                    // some second_category are missing
138
                    if (!isset($o[2][$value['second_category']])) {
139
                        $o[2][$value['second_category']] = [
140
                            'code' => $value['second_category'],
141
                            'name' => $value['name'],
142
                            'description' => $o[1][$value['first_category']]['description'],
143
                            'parent' => $value['first_category'],
144
                            'selected' => ($selected['code'] == $value['code']),
145
                        ];
146
                    }
147
                    break;
148
                default:
149
                    break;
150
            }
151
        }
152
153
        return $o;
154
    }
155
156
    private function simplifyItemDataArray($item, $parentKey = null, $selectedValue = null)
157
    {
158
        $o = [
159
            'code' => $item['code'],
160
            'name' => $item['name'],
161
            'description' => $item['description'],
162
            'selected' => ($selectedValue && ($item['code'] == $selectedValue)),
163
        ];
164
        if ($parentKey) {
165
            $o['parent'] = $item[$parentKey];
166
        }
167
168
        return $o;
169
    }
170
171
    public function getByName($name)
172
    {
173
        foreach ($this->data as $value) {
174
            if ($value['name'] === $name) {
175
                return $value;
176
            }
177
        }
178
    }
179
180
    public function getByTopCategory($categoryValue)
181
    {
182
        return $this->getByCategory('top_category', $categoryValue);
183
    }
184
185
    public function getByFirstCategory($categoryValue)
186
    {
187
        return $this->getByCategory('first_category', $categoryValue);
188
    }
189
190
    public function getBySecondCategory($categoryValue)
191
    {
192
        return $this->getByCategory('second_category', $categoryValue);
193
    }
194
195
    public function getByThirdCategory($categoryValue)
196
    {
197
        return $this->getByCode($categoryValue);
198
    }
199
200
    private function getByCategory($categoryKey, $categoryValue)
201
    {
202
        $o = [];
203
        foreach ($this->data as $key => $value) {
204
            if ($value[$categoryKey] === $categoryValue) {
205
                $o[$key] = $value;
206
            }
207
        }
208
        return $o;
209
    }
210
}
211