Completed
Push — development ( ef9e73...b2c3e4 )
by Andrij
20:27
created

Morphy::morphyWord()   C

Complexity

Conditions 7
Paths 11

Size

Total Lines 40
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 7
eloc 24
c 1
b 0
f 0
nc 11
nop 2
dl 0
loc 40
rs 6.7272
1
<?php namespace CMSFactory\Services\Morphy;
2
3
use phpMorphy;
4
5
/**
6
 * Service: morphy
7
 * Class Morphy
8
 * @package CMSFactory\Services\Morphy
9
 */
10
class Morphy
11
{
0 ignored issues
show
introduced by
Opening brace of a class must be on the same line as the definition
Loading history...
12
13
    /**
14
     * @var array
15
     */
16
    private $cases = [
17
                      1 => 'ИМ',//Именительный
0 ignored issues
show
introduced by
Expected one space after the comma, 0 found
Loading history...
18
                      2 => 'РД',//Родительный
0 ignored issues
show
introduced by
Expected one space after the comma, 0 found
Loading history...
19
                      3 => 'ДТ',//Дательный
0 ignored issues
show
introduced by
Expected one space after the comma, 0 found
Loading history...
20
                      4 => 'ВН',//Винительный
0 ignored issues
show
introduced by
Expected one space after the comma, 0 found
Loading history...
21
                      5 => 'ТВ',//Творительный
0 ignored issues
show
introduced by
Expected one space after the comma, 0 found
Loading history...
22
                      6 => 'ПР',//Предложный
0 ignored issues
show
introduced by
Expected one space after the comma, 0 found
Loading history...
23
                     ];
24
25
    const PLURAL = 'МН';
26
    const SINGULAR = 'ЕД';
27
28
    /**
29
     * method processing meta data
30
     * @var phpMorphy
31
     */
32
    private $phpMorphy;
33
34
    private $wordsCache = [];
35
36
    /**
37
     * Morphy constructor
38
     * @param phpMorphy $phpMorphy
39
     */
40
    public function __construct(phpMorphy $phpMorphy) {
41
        $this->phpMorphy = $phpMorphy;
42
    }
43
44
    /**
45
     * @param string $string
46
     * @param int $case
47
     * @return mixed|string
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use string.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
introduced by
@return tag is not required for constructor and destructor
Loading history...
48
     */
49
    public function morphy($string, $case = 1) {
50
51
        if (array_key_exists($case, $this->cases)) {
52
53
            $case = $this->cases[$case];
54
55
            $arrayString = explode(' ', $string);
56
            $arrayString = array_map(
57
                function ($word) use ($case) {
58
                    return $this->morphyWord($word, $case);
59
                },
60
                $arrayString
61
            );
62
63
            $string = implode(' ', $arrayString);
64
        }
65
        return $string;
66
67
    }
68
69
    /**
70
     * @param string $word
71
     * @param string $case
72
     * @return mixed|string
73
     */
74
    private function morphyWord($word, $case) {
75
        $word = trim($word);
76
        $key = $word . '_' . $case;
77
78
        if (!isset($this->wordsCache[$key])) {
79
80
            $initialString = $word;
81
            $request = [$case];
82
83
            $stringCase = $this->getStrCase($word);
84
85
            $word = mb_strtoupper($word, $this->phpMorphy->getEncoding());
86
87
            $res = $this->phpMorphy->getGramInfo($word)[0][0]['grammems'];
88
89
            $converted = false;
90
            if (is_array($res)) {
91
                $form = in_array(self::PLURAL, $res) ? self::PLURAL : self::SINGULAR;
92
                array_push($request, $form);
93
94
                $cast = $this->phpMorphy->castFormByGramInfo($word, null, $request, true);
95
96
                if (is_array($cast)) {
97
                    $word = array_shift($cast);
98
                    $converted = true;
99
                }
100
            }
101
102
            if ($converted && $word != '') {
103
                $word = mb_convert_case($word, $stringCase);
104
            } else {
105
                $word = $initialString;
106
            }
107
108
        } else {
109
            $word = $this->wordsCache[$word];
110
        }
111
112
        return $word;
113
    }
114
115
    /**
116
     * @param string $string
117
     * @return int
118
     */
119
    private function getStrCase($string) {
120
        if (mb_strtoupper($string) == $string) {
121
            return MB_CASE_UPPER;
122
        } elseif (mb_strtolower($string) == $string) {
123
            return MB_CASE_LOWER;
124
        }
125
        return MB_CASE_TITLE;
126
    }
127
}