From 98401fc8207ed2fd04f63d6286ca5d105aa1be01 Mon Sep 17 00:00:00 2001 From: wapmorgan Date: Sat, 6 May 2017 19:45:53 +0300 Subject: [PATCH] =?UTF-8?q?Add=20support=20for=20complex=20geographical=20?= =?UTF-8?q?names:=20=D0=9D=D0=B8=D0=B6=D0=BD=D0=B8=D0=B9=20=D0=9D=D0=BE?= =?UTF-8?q?=D0=B2=D0=B3=D0=BE=D1=80=D0=BE=D0=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Russian/GeographicalNamesDeclension.php | 35 ++++++++++++++++++- .../GeographicalNamesDeclensionTest.php | 1 + 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/Russian/GeographicalNamesDeclension.php b/src/Russian/GeographicalNamesDeclension.php index a1e5622..26b7f16 100644 --- a/src/Russian/GeographicalNamesDeclension.php +++ b/src/Russian/GeographicalNamesDeclension.php @@ -31,8 +31,41 @@ static public function isMutable($name) { static public function getCases($name) { $name = S::lower($name); + + // check for name of two words + if (strpos($name, ' ') !== false) { + $parts = explode(' ', $name); + $cases = array(); + $result = array(); + foreach ($parts as $i => $part) { + $result[$i] = static::getCases($part); + if ($i > 0) + $result[$i][self::PREDLOJ] = substr(strstr($result[$i][self::PREDLOJ], ' '), 1); + } + + $cases = array(); + foreach (array(self::IMENIT, self::RODIT, self::DAT, self::VINIT, self::TVORIT, self::PREDLOJ) as $case) { + foreach ($parts as $i => $part) { + $cases[$case][] = $result[$i][$case]; + } + $cases[$case] = implode(' ', $cases[$case]); + } + return $cases; + } + if (!in_array($name, self::$abbreviations)) { - if (S::slice($name, -1) == 'а') { + if (S::slice($name, -2) == 'ий') { + // Нижний, Русский + $prefix = S::name(S::slice($name, 0, -2)); + return array( + self::IMENIT => $prefix.'ий', + self::RODIT => $prefix.(self::isVelarConsonant(S::slice($name, -3, -2)) ? 'ого' : 'его'), + self::DAT => $prefix.(self::isVelarConsonant(S::slice($name, -3, -2)) ? 'ому' : 'ему'), + self::VINIT => $prefix.'ий', + self::TVORIT => $prefix.'им', + self::PREDLOJ => self::choosePrepositionByFirstLetter($prefix, 'об', 'о').' '.$prefix.'ем', + ); + } else if (S::slice($name, -1) == 'а') { // Москва, Рига $prefix = S::name(S::slice($name, 0, -1)); return array( diff --git a/tests/Russian/GeographicalNamesDeclensionTest.php b/tests/Russian/GeographicalNamesDeclensionTest.php index b8e8be5..3b95d86 100644 --- a/tests/Russian/GeographicalNamesDeclensionTest.php +++ b/tests/Russian/GeographicalNamesDeclensionTest.php @@ -25,6 +25,7 @@ public function wordsProvider() { array('Азия', array('Азия', 'Азии', 'Азии', 'Азию', 'Азией', 'об Азии')), array('Рига', array('Рига', 'Риги', 'Риге', 'Ригу', 'Ригой', 'о Риге')), array('Волга', array('Волга', 'Волги', 'Волге', 'Волгу', 'Волгой', 'о Волге')), + array('Нижний Новгород', array('Нижний Новгород', 'Нижнего Новгорода', 'Нижнему Новгороду', 'Нижний Новгород', 'Нижним Новгородом', 'о Нижнем Новгороде')), ); }