LastNamesInflection::getCase()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2.0185

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 3
dl 0
loc 10
ccs 5
cts 6
cp 0.8333
crap 2.0185
rs 9.9332
c 0
b 0
f 0
1
<?php
2
namespace morphos\Russian;
3
4
use morphos\S;
5
6
/**
7
 * Rules are from http://gramma.ru/SPR/?id=2.8
8
 */
9
class LastNamesInflection extends \morphos\NamesInflection implements Cases
10
{
11
    use RussianLanguage, CasesHelper;
12
13
    /** @var string[] */
14
    protected static $womenPostfixes = ['ва', 'на', 'ая', 'яя'];
15
    /** @var string[] */
16
    protected static $menPostfixes = ['ов', 'ев' ,'ин' ,'ын', 'ой', 'ий'];
17
18
    /**
19
     * @param string $name
20
     * @param string|null $gender
21
     * @return bool
22
     */
23 66
    public static function isMutable($name, $gender = null)
24
    {
25 66
        $name = S::lower($name);
26 66
        if ($gender === null) {
27
            $gender = static::detectGender($name);
28
        }
29
        // составная фамилия - разбить на части и проверить по отдельности
30 66
        if (strpos($name, '-') !== false) {
31 3
            foreach (explode('-', $name) as $part) {
32 3
                if (static::isMutable($part, $gender))
33 3
                    return true;
34
            }
35
            return false;
36
        }
37
38 66 View Code Duplication
        if (in_array(S::slice($name, -1), ['а', 'я'], true)) {
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...
39 28
            return true;
40
        }
41
        
42
        // Несклоняемые фамилии независимо от пола (Токаревских)
43 39 View Code Duplication
        if (in_array(S::slice($name, -2), ['их'], true))
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...
44
            return false;
45
46 39
        if ($gender == static::MALE) {
47
            // Несклоняемые фамилии (Фоминых, Седых / Стецко, Писаренко)
48 38 View Code Duplication
            if (in_array(S::slice($name, -2), ['ых', 'ко'], true))
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...
49 1
                return false;
50
51
            // Несклоняемые, образованные из родительного падежа личного или прозвищного имени главы семьи
52
            // суффиксы: ово, аго
53 37 View Code Duplication
            if (in_array(S::slice($name, -3), ['ово', 'аго'], true))
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...
54 1
                return false;
55
56
            // Типичные суффикс мужских фамилий
57 36
            if (in_array(S::slice($name, -2), ['ов', 'ев', 'ин', 'ын', 'ий', 'ой'], true)) {
58 13
                return true;
59
            }
60
61
            // Согласная на конце
62 23
            if (static::isConsonant(S::slice($name, -1))) {
63 15
                return true;
64
            }
65
66
            // Мягкий знак на конце
67 8
            if (S::slice($name, -1) == 'ь') {
68 8
                return true;
69
            }
70
71 View Code Duplication
        } else {
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...
72
            // Типичные суффиксы женских фамилий
73 1
            if (in_array(S::slice($name, -2), ['ва', 'на', 'ая'], true)) {
74
                return true;
75
            }
76
        }
77
78 3
        return false;
79
    }
80
81
    /**
82
     * @param string $name
83
     * @return null|string
84
     */
85 25
    public static function detectGender($name)
86
    {
87 25
        $name = S::lower($name);
88 25
        if (in_array(S::slice($name, -2), static::$menPostfixes, true)) {
89 6
            return static::MALE;
90
        }
91 20
        if (in_array(S::slice($name, -2), static::$womenPostfixes, true)) {
92 6
            return static::FEMALE;
93
        }
94
95 14
        return null;
96
    }
97
98
    /**
99
     * @param string $name
100
     * @param null|string $gender
101
     * @return string[]
102
     * @phpstan-return array<string, string>
103
     */
104 39
    public static function getCases($name, $gender = null)
105
    {
106 39
        $name = S::lower($name);
107 39
        if ($gender === null) {
108
            $gender = static::detectGender($name);
109
        }
110
111
        // составная фамилия - разбить на части и склонять по отдельности
112 39
        if (strpos($name, '-') !== false) {
113 3
            $parts = explode('-', $name);
114 3
            $cases = [];
0 ignored issues
show
Unused Code introduced by
$cases is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
115 3
            foreach ($parts as $i => $part) {
116 3
                $parts[$i] = static::getCases($part, $gender);
117
            }
118
119 3
            return static::composeCasesFromWords($parts, '-');
120
        }
121
122 39
        if (static::isMutable($name, $gender)) {
123 38
            if ($gender == static::MALE) {
124 24
                if (in_array(S::slice($name, -2), ['ов', 'ев', 'ин', 'ын', 'ёв'], true)) {
125 5
                    $prefix = S::name($name);
126
                    return [
0 ignored issues
show
Best Practice introduced by
The expression return array(static::IME...LOJ => $prefix . 'е'); seems to be an array, but some of its elements' types (boolean) are incompatible with the return type documented by morphos\Russian\LastNamesInflection::getCases of type string[].

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
127 5
                        static::IMENIT => $prefix,
128 5
                        static::RODIT => $prefix.'а',
129 5
                        static::DAT => $prefix.'у',
130 5
                        static::VINIT => $prefix.'а',
131 5
                        static::TVORIT => $prefix.'ым',
132 5
                        static::PREDLOJ => $prefix.'е'
133
                    ];
134 19 View Code Duplication
                } elseif (in_array(S::slice($name, -4), ['ский', 'ской', 'цкий', 'цкой'], true)) {
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...
135 1
                    $prefix = S::name(S::slice($name, 0, -2));
136
                    return [
0 ignored issues
show
Best Practice introduced by
The expression return array(static::IME...J => $prefix . 'ом'); seems to be an array, but some of its elements' types (boolean) are incompatible with the return type documented by morphos\Russian\LastNamesInflection::getCases of type string[].

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
137 1
                        static::IMENIT => S::name($name),
138 1
                        static::RODIT => $prefix.'ого',
139 1
                        static::DAT => $prefix.'ому',
140 1
                        static::VINIT => $prefix.'ого',
141 1
                        static::TVORIT => $prefix.'им',
142 1
                        static::PREDLOJ => $prefix.'ом'
143
                    ];
144
                // Верхний / Убогий / Толстой
145
                // Верхнего / Убогого / Толстого
146
                // Верхнему / Убогому / Толстому
147
                // Верхним / Убогим / Толстым
148
                // О Верхнем / Об Убогом / О Толстом
149 18
                } else if (in_array(S::slice($name, -2), ['ой', 'ый', 'ий'], true)) {
150 3
                    $prefix = S::name(S::slice($name, 0, -2));
151
                    return [
0 ignored issues
show
Best Practice introduced by
The expression return array(static::IME...J => $prefix . 'ом'); seems to be an array, but some of its elements' types (boolean) are incompatible with the return type documented by morphos\Russian\LastNamesInflection::getCases of type string[].

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
152 3
                        static::IMENIT => S::name($name),
153 3
                        static::RODIT => $prefix.'ого',
154 3
                        static::DAT => $prefix.'ому',
155 3
                        static::VINIT => $prefix.'ого',
156 3
                        static::TVORIT => $prefix.'ым',
157 18
                        static::PREDLOJ => $prefix.'ом'
158
                    ];
159
                }
160
161
            } else {
162 14 View Code Duplication
                if (in_array(S::slice($name, -3), ['ова', 'ева', 'ина', 'ына', 'ёва'], true)) {
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...
163 5
                    $prefix = S::name(S::slice($name, 0, -1));
164
                    return [
0 ignored issues
show
Best Practice introduced by
The expression return array(static::IME...J => $prefix . 'ой'); seems to be an array, but some of its elements' types (boolean) are incompatible with the return type documented by morphos\Russian\LastNamesInflection::getCases of type string[].

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
165 5
                        static::IMENIT => S::name($name),
166 5
                        static::RODIT => $prefix.'ой',
167 5
                        static::DAT => $prefix.'ой',
168 5
                        static::VINIT => $prefix.'у',
169 5
                        static::TVORIT => $prefix.'ой',
170 5
                        static::PREDLOJ => $prefix.'ой'
171
                    ];
172
                }
173
174 9
                if (in_array(S::slice($name, -2), ['ая'], true)) {
175 3
                    $prefix = S::name(S::slice($name, 0, -2));
176
                    return [
0 ignored issues
show
Best Practice introduced by
The expression return array(static::IME...J => $prefix . 'ой'); seems to be an array, but some of its elements' types (boolean) are incompatible with the return type documented by morphos\Russian\LastNamesInflection::getCases of type string[].

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
177 3
                        static::IMENIT => S::name($name),
178 3
                        static::RODIT => $prefix.'ой',
179 3
                        static::DAT => $prefix.'ой',
180 3
                        static::VINIT => $prefix.'ую',
181 3
                        static::TVORIT => $prefix.'ой',
182 3
                        static::PREDLOJ => $prefix.'ой'
183
                    ];
184
                }
185
186 6
                if (in_array(S::slice($name, -2), ['яя'], true)) {
187 1
                    $prefix = S::name(S::slice($name, 0, -2));
188
                    return [
0 ignored issues
show
Best Practice introduced by
The expression return array(static::IME...J => $prefix . 'ей'); seems to be an array, but some of its elements' types (boolean) are incompatible with the return type documented by morphos\Russian\LastNamesInflection::getCases of type string[].

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
189 1
                        static::IMENIT => S::name($name),
190 1
                        static::RODIT => $prefix.'ей',
191 1
                        static::DAT => $prefix.'ей',
192 1
                        static::VINIT => $prefix.'юю',
193 1
                        static::TVORIT => $prefix.'ей',
194 1
                        static::PREDLOJ => $prefix.'ей'
195
                    ];
196
                }
197
            }
198
199 20
            if (S::slice($name, -1) == 'я') {
200 1
                $prefix = S::name(S::slice($name, 0, -1));
201
                return [
0 ignored issues
show
Best Practice introduced by
The expression return array(static::IME...LOJ => $prefix . 'е'); seems to be an array, but some of its elements' types (boolean) are incompatible with the return type documented by morphos\Russian\LastNamesInflection::getCases of type string[].

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
202 1
                    static::IMENIT => S::name($name),
203 1
                    static::RODIT => $prefix.'и',
204 1
                    static::DAT => $prefix.'е',
205 1
                    static::VINIT => $prefix.'ю',
206 1
                    static::TVORIT => $prefix.'ей',
207 1
                    static::PREDLOJ => $prefix.'е'
208
                ];
209 19
            } elseif (S::slice($name, -1) == 'а') {
210 7
                $prefix = S::name(S::slice($name, 0, -1));
211
                return [
0 ignored issues
show
Best Practice introduced by
The expression return array(static::IME...LOJ => $prefix . 'е'); seems to be an array, but some of its elements' types (boolean) are incompatible with the return type documented by morphos\Russian\LastNamesInflection::getCases of type string[].

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
212 7
                    static::IMENIT => S::name($name),
213 7
                    static::RODIT => $prefix.((static::isDeafConsonant(S::slice($name, -2, -1)) && S::slice($name, -2, -1) !== 'п')
214 7
                        || S::slice($name, -2) === 'га' ? 'и' : 'ы'),
215 7
                    static::DAT => $prefix.'е',
216 7
                    static::VINIT => $prefix.'у',
217 7
                    static::TVORIT => $prefix.'ой',
218 7
                    static::PREDLOJ => $prefix.'е'
219
                ];
220 12
            } elseif (static::isConsonant(S::slice($name, -1)) && S::slice($name, -2) !== 'ых') {
221 9
                $prefix = S::name($name);
222
                return [
0 ignored issues
show
Best Practice introduced by
The expression return array(static::IME...LOJ => $prefix . 'е'); seems to be an array, but some of its elements' types (boolean) are incompatible with the return type documented by morphos\Russian\LastNamesInflection::getCases of type string[].

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
223 9
                    static::IMENIT => S::name($name),
224 9
                    static::RODIT => $prefix.'а',
225 9
                    static::DAT => $prefix.'у',
226 9
                    static::VINIT => $prefix.'а',
227 9
                    static::TVORIT => $prefix.'ом',
228 9
                    static::PREDLOJ => $prefix.'е'
229
                ];
230 3
            } elseif (S::slice($name, -1) == 'ь' && $gender == static::MALE) {
231 3
                $prefix = S::name(S::slice($name, 0, -1));
232
                return [
0 ignored issues
show
Best Practice introduced by
The expression return array(static::IME...LOJ => $prefix . 'е'); seems to be an array, but some of its elements' types (boolean) are incompatible with the return type documented by morphos\Russian\LastNamesInflection::getCases of type string[].

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
233 3
                    static::IMENIT => S::name($name),
234 3
                    static::RODIT => $prefix.'я',
235 3
                    static::DAT => $prefix.'ю',
236 3
                    static::VINIT => $prefix.'я',
237 3
                    static::TVORIT => $prefix.'ем',
238 3
                    static::PREDLOJ => $prefix.'е'
239
                ];
240
            }
241
        }
242
243 2
        $name = S::name($name);
244 2
        return array_fill_keys([static::IMENIT, static::RODIT, static::DAT, static::VINIT, static::TVORIT, static::PREDLOJ], $name);
245
    }
246
247
    /**
248
     * @param string $name
249
     * @param string $case
250
     * @param null $gender
251
     * @return string
252
     * @throws \Exception
253
     */
254 6
    public static function getCase($name, $case, $gender = null)
255
    {
256 6
        if (!static::isMutable($name, $gender)) {
257
            return $name;
258
        } else {
259 6
            $case = static::canonizeCase($case);
260 6
            $forms = static::getCases($name, $gender);
261 6
            return $forms[$case];
262
        }
263
    }
264
}
265