Completed
Push — master ( c8a008...075722 )
by f
01:46
created

CardinalNumber   A

Complexity

Total Complexity 31

Size/Duplication

Total Lines 228
Duplicated Lines 8.33 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
dl 19
loc 228
rs 9.8
c 0
b 0
f 0
wmc 31
lcom 1
cbo 4

2 Methods

Rating   Name   Duplication   Size   Complexity  
F getForms() 19 112 30
A getForm() 0 4 1

How to fix   Duplicated Code   

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:

1
<?php
2
namespace morphos\Russian;
3
4
use morphos\NumberCreation;
5
6
/**
7
 * Rules are from http://www.fio.ru/pravila/grammatika/sklonenie-imen-chislitelnykh/
8
 */
9
class CardinalNumber extends NumberCreation implements Cases {
10
    use RussianLanguage;
11
12
    protected $words = array(
13
        1 => 'один',
14
        2 => 'два',
15
        3 => 'три',
16
        4 => 'четыре',
17
        5 => 'пять',
18
        6 => 'шесть',
19
        7 => 'семь',
20
        8 => 'восемь',
21
        9 => 'девять',
22
        10 => 'десять',
23
        11 => 'одиннадцать',
24
        12 => 'двенадцать',
25
        13 => 'тринадцать',
26
        14 => 'четырнадцать',
27
        15 => 'пятнадцать',
28
        16 => 'шестнадцать',
29
        17 => 'семнадцать',
30
        18 => 'восемнадцать',
31
        19 => 'девятнадцать',
32
        20 => 'двадцать',
33
        30 => 'тридцать',
34
        40 => 'сорок',
35
        50 => 'пятьдесят',
36
        60 => 'шестьдесят',
37
        70 => 'семьдесят',
38
        80 => 'восемьдесят',
39
        90 => 'девяносто',
40
        100 => 'сто',
41
        200 => 'двести',
42
        300 => 'триста',
43
        400 => 'четыреста',
44
        500 => 'пятьсот',
45
        600 => 'шестьсот',
46
        700 => 'семьсот',
47
        800 => 'восемьсот',
48
        900 => 'девятьсот',
49
    );
50
51
    protected $exponents = array(
52
        1000 => 'тысяча',
53
        1000000 => 'миллион',
54
        1000000000 => 'миллиард',
55
    );
56
57
    protected $declension;
58
    protected $plurality;
59
60
    protected $precalculated = array(
61
        'один' => array(
62
            self::IMENIT => 'один',
63
            self::RODIT => 'одного',
64
            self::DAT => 'одному',
65
            self::VINIT => 'один',
66
            self::TVORIT => 'одним',
67
            self::PREDLOJ => 'об одном',
68
        ),
69
        'два' => array(
70
            self::IMENIT => 'два',
71
            self::RODIT => 'двух',
72
            self::DAT => 'двум',
73
            self::VINIT => 'два',
74
            self::TVORIT => 'двумя',
75
            self::PREDLOJ => 'о двух',
76
        ),
77
        'три' => array(
78
            self::IMENIT => 'три',
79
            self::RODIT => 'трех',
80
            self::DAT => 'трем',
81
            self::VINIT => 'три',
82
            self::TVORIT => 'тремя',
83
            self::PREDLOJ => 'о трех',
84
        ),
85
        'четыре' => array(
86
            self::IMENIT => 'четыре',
87
            self::RODIT => 'четырех',
88
            self::DAT => 'четырем',
89
            self::VINIT => 'четыре',
90
            self::TVORIT => 'четырьмя',
91
            self::PREDLOJ => 'о четырех',
92
        ),
93
        'двести' => array(
94
            self::IMENIT => 'двести',
95
            self::RODIT => 'двухсот',
96
            self::DAT => 'двумстам',
97
            self::VINIT => 'двести',
98
            self::TVORIT => 'двумястами',
99
            self::PREDLOJ => 'о двухстах',
100
        ),
101
        'восемьсот' => array(
102
            self::IMENIT => 'восемьсот',
103
            self::RODIT => 'восьмисот',
104
            self::DAT => 'восьмистам',
105
            self::VINIT => 'восемьсот',
106
            self::TVORIT => 'восьмистами',
107
            self::PREDLOJ => 'о восьмистах',
108
        ),
109
        'тысяча' => array(
110
            self::IMENIT => 'тысяча',
111
            self::RODIT => 'тысяч',
112
            self::DAT => 'тысячам',
113
            self::VINIT => 'тысяч',
114
            self::TVORIT => 'тысячей',
115
            self::PREDLOJ => 'о тысячах',
116
        ),
117
    );
118
119
    public function getForms($number) {
120
        // simple numeral
121
        if (isset($this->words[$number]) || isset($this->exponents[$number])) {
122
            $word = isset($this->words[$number]) ? $this->words[$number] : $this->exponents[$number];
123
            if (isset($this->precalculated[$word])) {
124
                return $this->precalculated[$word];
125
            } else if (($number >= 5 && $number <= 20) || $number == 30) {
126
                $prefix = slice($word, 0, -1);
127
                return array(
128
                    self::IMENIT => $word,
129
                    self::RODIT => $prefix.'и',
130
                    self::DAT => $prefix.'и',
131
                    self::VINIT => $word,
132
                    self::TVORIT => $prefix.'ью',
133
                    self::PREDLOJ => $this->choosePrepositionByFirstLetter($prefix, 'об', 'о').' '.$prefix.'и',
134
                );
135
            } else if (in_array($number, array(40, 90, 100))) {
136
                $prefix = $number == 40 ? $word : slice($word, 0, -1);
137
                return array(
138
                    self::IMENIT => $word,
139
                    self::RODIT => $prefix.'а',
140
                    self::DAT => $prefix.'а',
141
                    self::VINIT => $word,
142
                    self::TVORIT => $prefix.'а',
143
                    self::PREDLOJ => $this->choosePrepositionByFirstLetter($prefix, 'об', 'о').' '.$prefix.'а',
144
                );
145
            } else if (($number >= 50 && $number <= 80)) {
146
                $prefix = slice($word, 0, -6);
147
                return array(
148
                    self::IMENIT => $prefix.'ьдесят',
149
                    self::RODIT => $prefix.'идесяти',
150
                    self::DAT => $prefix.'идесяти',
151
                    self::VINIT => $prefix.'ьдесят',
152
                    self::TVORIT => $prefix.'ьюдесятью',
153
                    self::PREDLOJ => $this->choosePrepositionByFirstLetter($word, 'об', 'о').' '.$prefix.'идесяти',
154
                );
155
            } else if (in_array($number, array(300, 400))) {
156
                $prefix = slice($word, 0, -4);
157
                return array(
158
                    self::IMENIT => $word,
159
                    self::RODIT => $prefix.'ехсот',
160
                    self::DAT => $prefix.'емстам',
161
                    self::VINIT => $word,
162
                    self::TVORIT => $prefix.($number == 300 ? 'е' : 'ь').'мястами',
163
                    self::PREDLOJ => $this->choosePrepositionByFirstLetter($word, 'об', 'о').' '.$prefix.'ехстах',
164
                );
165
            } else if ($number >= 500 && $number <= 900) {
166
                $prefix = slice($word, 0, -4);
167
                return array(
168
                    self::IMENIT => $word,
169
                    self::RODIT => $prefix.'исот',
170
                    self::DAT => $prefix.'истам',
171
                    self::VINIT => $word,
172
                    self::TVORIT => $prefix.'ьюстами',
173
                    self::PREDLOJ => $this->choosePrepositionByFirstLetter($word, 'об', 'о').' '.$prefix.'истах',
174
                );
175
            }
176
        }
177
        // compound numeral
178
        else {
179
            $parts = array();
180
            $result = array();
181
182
            foreach (array_reverse($this->exponents, true) as $word_number => $word) {
183
                if ($number >= $word_number) {
184
                    $count = floor($number / $word_number);
185
                    $parts[] = $this->getForms($count);
186
187
                    // get forms of word
188
                    if (empty($this->declension)) $this->declension = new GeneralDeclension();
189
                    if (empty($this->plurality)) $this->plurality = new Plurality();
190
191
                    switch (Plurality::getNumeralForm($count)) {
192
                        case Plurality::ONE:
193
                            $parts[] = $this->declension->getForms($word, false);
194
                            break;
195 View Code Duplication
                        case Plurality::TWO_FOUR:
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...
196
                            $part = $this->plurality->getForms($word);
197
                            if ($word_number != 1000) // get dative case of word for 1000000 and 1000000000
198
                                $part[Cases::IMENIT] = $part[Cases::VINIT] = $this->declension->getForm($word, Cases::RODIT);
199
                            $parts[] = $part;
200
                            break;
201 View Code Duplication
                        case Plurality::FIVE_OTHER:
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...
202
                            $part = $this->plurality->getForms($word);
203
                            $part[Cases::IMENIT] = $part[Cases::VINIT] = $part[Cases::RODIT];
204
                            $parts[] = $part;
205
                            break;
206
                    }
207
208
                    $number = $number % ($count * $word_number);
209
                }
210
            }
211
212
            foreach (array_reverse($this->words, true) as $word_number => $word) {
213
                if ($number >= $word_number) {
214
                    $parts[] = $this->getForms($word_number);
215
                    $number %= $word_number;
216
                }
217
            }
218
219 View Code Duplication
            foreach (array(self::IMENIT, self::RODIT, self::DAT, self::VINIT, self::TVORIT, self::PREDLOJ) as $case) {
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...
220
                $result[$case] = array();
221
                foreach ($parts as $partN => $part) {
222
                    if ($case == self::PREDLOJ && $partN > 0) list(, $part[$case]) = explode(' ', $part[$case], 2);
223
                    $result[$case][] = $part[$case];
224
                }
225
                $result[$case] = implode(' ', $result[$case]);
226
            }
227
228
            return $result;
229
        }
230
    }
231
232
    public function getForm($number, $form) {
0 ignored issues
show
Unused Code introduced by
The parameter $number is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
233
        $forms = $this->getForms($name);
0 ignored issues
show
Bug introduced by
The variable $name does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
234
        return $forms[$form];
235
    }
236
}
237