From aa6457b3e25129a5c39c3335a6b5a2f788b7b082 Mon Sep 17 00:00:00 2001 From: Andriy Chaika Date: Tue, 5 Jul 2011 20:22:03 +0300 Subject: [PATCH] =?UTF-8?q?[0.4]=20=D0=9F=D0=B5=D1=80=D0=B5=D0=BF=D0=B8?= =?UTF-8?q?=D1=81=D0=B0=D0=BD=D0=BE=20=D1=8F=D0=B4=D1=80=D0=BE=20=D0=B8=20?= =?UTF-8?q?=D1=83=D0=BA=D1=80=D0=B0=D0=B8=D0=BD=D1=81=D0=BA=D0=B0=20=D0=B2?= =?UTF-8?q?=D0=B5=D1=80=D1=81=D0=B8=D1=8F=20=D0=B1=D0=B8=D0=B1=D0=BB=D0=B8?= =?UTF-8?q?=D0=BE=D1=82=D0=B5=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Library/NCL.NameCase.ua.php | 260 +++++------- Library/NCL/NCLNameCaseCore.php | 586 +++++++++++++-------------- Library/NCL/NCLNameCaseInterface.php | 4 - Library/NCL/NCLNameCaseWord.php | 142 ++++++- Library/NCL/NCLStr.php | 10 + Tests/debug.php | 2 +- 6 files changed, 510 insertions(+), 494 deletions(-) diff --git a/Library/NCL.NameCase.ua.php b/Library/NCL.NameCase.ua.php index dc8b923..2d02bf8 100644 --- a/Library/NCL.NameCase.ua.php +++ b/Library/NCL.NameCase.ua.php @@ -256,7 +256,7 @@ class NCLNameCaseUa extends NCLNameCaseCore implements NCLNameCaseInterface //Випадання букви е при відмінюванні слів типу Орел - if (NCLStr::substr($osnova, 0, 1) == 'О' and $this->FirstLastVowel($osnova, $this->vowels . 'гк') == 'е' and $this->Last(2) != 'сь') + if (NCLStr::substr($osnova, 0, 1) == 'о' and $this->FirstLastVowel($osnova, $this->vowels . 'гк') == 'е' and $this->Last(2) != 'сь') { $delim = NCLStr::strrpos($osnova, 'е'); $osnova = NCLStr::substr($osnova, 0, $delim) . NCLStr::substr($osnova, $delim + 1, NCLStr::strlen($osnova) - $delim); @@ -433,7 +433,7 @@ class NCLNameCaseUa extends NCLNameCaseCore implements NCLNameCaseInterface { if ($this->in($this->Last(1), $this->consonant . 'ь')) { - $osnova = $this->getOsnova($this->firstName); + $osnova = $this->getOsnova($this->workingWord); $apostrof = ''; $duplicate = ''; $osLast = NCLStr::substr($osnova, -1, 1); @@ -503,18 +503,7 @@ class NCLNameCaseUa extends NCLNameCaseCore implements NCLNameCaseInterface */ protected function manFirstName() { - - $this->setWorkingWord($this->firstName); - - if ($this->RulesChain('man', array(1, 2, 3))) - { - $this->frule = $this->lastRule; - $this->firstResult = $this->lastResult; - } - else - { - $this->makeFirstTheSame(); - } + return $this->RulesChain('man', array(1, 2, 3)); } /** @@ -524,17 +513,7 @@ class NCLNameCaseUa extends NCLNameCaseCore implements NCLNameCaseInterface */ protected function womanFirstName() { - $this->setWorkingWord($this->firstName); - - if ($this->RulesChain('woman', array(1, 2))) - { - $this->frule = $this->lastRule; - $this->firstResult = $this->lastResult; - } - else - { - $this->makeFirstTheSame(); - } + return $this->RulesChain('woman', array(1, 2)); } /* @@ -545,17 +524,7 @@ class NCLNameCaseUa extends NCLNameCaseCore implements NCLNameCaseInterface protected function manSecondName() { - $this->setWorkingWord($this->secondName); - - if ($this->RulesChain('man', array(5, 1, 2, 3, 4))) - { - $this->srule = $this->lastRule; - $this->secondResult = $this->lastResult; - } - else - { - $this->makeSecondTheSame(); - } + return $this->RulesChain('man', array(5, 1, 2, 3, 4)); } /* @@ -566,17 +535,7 @@ class NCLNameCaseUa extends NCLNameCaseCore implements NCLNameCaseInterface protected function womanSecondName() { - $this->setWorkingWord($this->secondName); - - if ($this->RulesChain('woman', array(3, 1))) - { - $this->srule = $this->lastRule; - $this->secondResult = $this->lastResult; - } - else - { - $this->makeSecondTheSame(); - } + return $this->RulesChain('woman', array(3, 1)); } /* @@ -587,18 +546,12 @@ class NCLNameCaseUa extends NCLNameCaseCore implements NCLNameCaseInterface protected function manFatherName() { - $this->setWorkingWord($this->fatherName); if ($this->in($this->Last(2), array('ич', 'іч'))) { $this->wordForms($this->workingWord, array('а', 'у', 'а', 'ем', 'у', 'у')); - $this->fatherResult = $this->lastResult; return true; } - else - { - $this->makeFatherTheSame(); - return false; - } + return false; } /* @@ -609,127 +562,97 @@ class NCLNameCaseUa extends NCLNameCaseCore implements NCLNameCaseInterface protected function womanFatherName() { - $this->setWorkingWord($this->fatherName); if ($this->in($this->Last(3), array('вна'))) { $this->wordForms($this->workingWord, array('и', 'і', 'у', 'ою', 'і', 'о'), 1); - $this->fatherResult = $this->lastResult; return true; } - else - { - $this->makeFatherTheSame(); - return false; - } + return false; } - /* - * Автоматическое определение пола - * @return void - */ - - protected function genderDetect() + protected function GenderByFirstName(NCLNameCaseWord $word) { + $this->setWorkingWord($word->getWord()); - //$this->gender = NCL::$MAN; // мужчина - if (!$this->gender) + $man = 0; //Мужчина + $woman = 0; //Женщина + //Попробуем выжать максимум из имени + //Если имя заканчивается на й, то скорее всего мужчина + if ($this->Last(1) == 'й') { - //Определение пола по отчеству - if (isset($this->fatherName) and $this->fatherName) - { - $LastTwo = mb_substr($this->fatherName, -2, 2, 'utf-8'); - if ($LastTwo == 'ич') - { - $this->gender = NCL::$MAN; // мужчина - return true; - } - if ($LastTwo == 'на') - { - $this->gender = NCL::$WOMAN; // женщина - return true; - } - } - $man = 0; //Мужчина - $woman = 0; //Женщина - - $FLastSymbol = mb_substr($this->firstName, -1, 1, 'utf-8'); - $FLastTwo = mb_substr($this->firstName, -2, 2, 'utf-8'); - $FLastThree = mb_substr($this->firstName, -3, 3, 'utf-8'); - $FLastFour = mb_substr($this->firstName, -4, 4, 'utf-8'); - - $SLastSymbol = mb_substr($this->secondName, -1, 1, 'utf-8'); - $SLastTwo = mb_substr($this->secondName, -2, 2, 'utf-8'); - $SLastThree = mb_substr($this->secondName, -3, 3, 'utf-8'); - - //Если нет отчества, то определяем по имени и фамилии, будем считать вероятность - if (isset($this->firstName) and $this->firstName) - { - //Попробуем выжать максимум из имени - //Если имя заканчивается на й, то скорее всего мужчина - if ($FLastSymbol == 'й') - { - $man+=0.9; - } - if (in_array($FLastTwo, array('он', 'ов', 'ав', 'ам', 'ол', 'ан', 'рд', 'мп', 'ко', 'ло'))) - { - $man+=0.5; - } - if (in_array($FLastThree, array('бов', 'нка', 'яра', 'ила'))) - { - $woman+=0.5; - } - if ($this->in($FLastSymbol, $this->consonant)) - { - $man+=0.01; - } - if ($FLastSymbol == 'ь') - { - $man+=0.02; - } - - if (in_array($FLastTwo, array('дь'))) - { - $woman+=0.1; - } - - if (in_array($FLastThree, array('ель', 'бов'))) - { - $woman+=0.4; - } - } - -// $man*=1.2; -// $woman*=1.2; - - if (isset($this->secondName) and $this->secondName) - { - if (in_array($SLastTwo, array('ов', 'ин', 'ев', 'єв', 'ін', 'їн', 'ий', 'їв', 'ів', 'ой', 'ей'))) - { - $man+=0.4; - } - - if (in_array($SLastThree, array('ова', 'ина', 'ева', 'єва', 'іна'))) - { - $woman+=0.4; - } - - if (in_array($SLastTwo, array('ая'))) - { - $woman+=0.4; - } - } - - //Теперь смотрим, кто больше набрал - if ($man > $woman) - { - $this->gender = NCL::$MAN; - } - else - { - $this->gender = NCL::$WOMAN; - } + $man+=0.9; + } + + if ($this->in($this->Last(2), array('он', 'ов', 'ав', 'ам', 'ол', 'ан', 'рд', 'мп', 'ко', 'ло'))) + { + $man+=0.5; + } + + if ($this->in($this->Last(3), array('бов', 'нка', 'яра', 'ила'))) + { + $woman+=0.5; + } + + if ($this->in($this->Last(1), $this->consonant)) + { + $man+=0.01; + } + + if ($this->Last(1) == 'ь') + { + $man+=0.02; + } + + if ($this->in($this->Last(2), array('дь'))) + { + $woman+=0.1; + } + + if ($this->in($this->Last(3), array('ель', 'бов'))) + { + $woman+=0.4; + } + + $word->setGender($man, $woman); + } + + protected function GenderBySecondName(NCLNameCaseWord $word) + { + $this->setWorkingWord($word->getWord()); + + $man = 0; //Мужчина + $woman = 0; //Женщина + + if ($this->in($this->Last(2), array('ов', 'ин', 'ев', 'єв', 'ін', 'їн', 'ий', 'їв', 'ів', 'ой', 'ей'))) + { + $man+=0.4; + } + + if ($this->in($this->Last(3), array('ова', 'ина', 'ева', 'єва', 'іна'))) + { + $woman+=0.4; + } + + if ($this->in($this->Last(2), array('ая'))) + { + $woman+=0.4; + } + + $word->setGender($man, $woman); + } + + protected function GenderByFatherName(NCLNameCaseWord $word) + { + $this->setWorkingWord($word->getWord()); + + if ($this->Last(2) == 'ич') + { + $word->setGender(10, 0); // мужчина + } + if ($this->Last(2) == 'на') + { + $word->setGender(0, 12); // женщина } - return true; } /* @@ -737,8 +660,9 @@ class NCLNameCaseUa extends NCLNameCaseCore implements NCLNameCaseInterface * @return integer $number - 1-фамили 2-имя 3-отчество */ - protected function detectNamePart($namepart) + protected function detectNamePart(NCLNameCaseWord $word) { + $namepart = $word->getWord(); $this->setWorkingWord($namepart); //Считаем вероятность @@ -785,15 +709,15 @@ class NCLNameCaseUa extends NCLNameCaseCore implements NCLNameCaseInterface if ($first == $max) { - return 'N'; + $word->setNamePart('N'); } elseif ($second == $max) { - return 'S'; + $word->setNamePart('S'); } else { - return 'F'; + $word->setNamePart('F'); } } diff --git a/Library/NCL/NCLNameCaseCore.php b/Library/NCL/NCLNameCaseCore.php index b140860..17f7d12 100644 --- a/Library/NCL/NCLNameCaseCore.php +++ b/Library/NCL/NCLNameCaseCore.php @@ -1,5 +1,6 @@ 0 - не известно - *
  • 1 - мужчина
  • - *
  • 2 - женщина
  • - */ - protected $gender = 0; - - /** DEPRECATED - * @var array() - * Результат склонения имени - */ - protected $firstResult = array(); - - - /** DEPRECATED - * @var array() - * Результат склонения фамилии - */ - protected $secondResult = array(); - - /** DEPRECATED - * @var array() - * Результат склонения отчества - */ - protected $fatherResult = array(); - - /* - * @var integer - * Номер правила по которому не склоняется имя/фамилия - */ - protected $error = ""; - - /** DEPRECATED - * @var integer - * Номер правила по которому склоняется имя - */ - protected $frule = ""; - - /** DEPRECATED - * @var integer - * Номер правила по которому не склоняется фамилия - */ - protected $srule = ""; - - /* * Слово с которым работаем сейчас * @var string @@ -108,6 +50,7 @@ class NCLNameCaseCore extends NCL * @var array */ protected $lastResult = array(); + protected $index = array(); /** * Сброс всех настроек @@ -117,7 +60,21 @@ class NCLNameCaseCore extends NCL $this->lastRule = 0; $this->lastResult = array(); } - + + protected function fullReset() + { + $this->words = array(); + $this->index = array('N' => array(), 'F' => array(), 'S' => array()); + $this->reset(); + $this->notReady(); + } + + protected function notReady() + { + $this->ready = false; + $this->finished = false; + } + /** * Установить номер парвила * @param int $index @@ -126,9 +83,7 @@ class NCLNameCaseCore extends NCL { $this->lastRule = $index; } - - - + /* * Установить текущее слово */ @@ -167,7 +122,7 @@ class NCLNameCaseCore extends NCL } return $this->workindLastCache[$length][$stopAfter]; } - + /** * Выполняет над словом типа $gender (man / woman) в порядке указанов в $rulesArray * @param string $gender - мужские/женский правила @@ -176,10 +131,10 @@ class NCLNameCaseCore extends NCL */ protected function RulesChain($gender, $rulesArray) { - foreach($rulesArray as $ruleID) + foreach ($rulesArray as $ruleID) { - $ruleMethod = $gender.'Rule'.$ruleID; - if($this->$ruleMethod()) + $ruleMethod = $gender . 'Rule' . $ruleID; + if ($this->$ruleMethod()) { return true; } @@ -187,33 +142,6 @@ class NCLNameCaseCore extends NCL return false; } - protected function makeFirstTheSame() - { - $this->firstResult = array_fill(0, $this->CaseCount, $this->firstName); - } - - /* - * Функция, которая ставит фамилию во всех падежах в форме именительного падежа. - * - * @return void - */ - - protected function makeSecondTheSame() - { - $this->secondResult = array_fill(0, $this->CaseCount, $this->secondName); - } - - /* - * Функция, которая ставит фамилию во всех падежах в форме именительного падежа. - * - * @return void - */ - - protected function makeFatherTheSame() - { - $this->fatherResult = array_fill(0, $this->CaseCount, $this->fatherName); - } - /* * Функция проверяет, входит ли буква в строку. * @@ -279,7 +207,7 @@ class NCLNameCaseCore extends NCL protected function wordForms($word, $endings, $replaceLast=0) { //Создаем массив с именительный падежом - $result = array($word); + $result = array($this->workingWord); //Убираем в окончание лишние буквы $word = NCLStr::substr($word, 0, NCLStr::strlen($word) - $replaceLast); @@ -292,31 +220,6 @@ class NCLNameCaseCore extends NCL $this->lastResult = $result; } - /* - * DEPRECATED!!! - */ - - protected function padeg($word, $endings, $replaceLast=false, $replaceTwoLast=false) - { - $result = array($word); - if ($replaceTwoLast == true) - { - //убираем последнею букву - $word = mb_substr($word, 0, mb_strlen($word, 'utf-8') - 2, 'utf-8'); - } - elseif ($replaceLast == true) - { - //убираем последнею букву - $word = mb_substr($word, 0, mb_strlen($word, 'utf-8') - 1, 'utf-8'); - } - $i = 0; - for ($i = 0; $i < ($this->CaseCount - 1); $i++) - { - $result[$i + 1] = $word . $endings[$i]; - } - return $result; - } - /* * Установка имени * @@ -327,7 +230,13 @@ class NCLNameCaseCore extends NCL public function setFirstName($firstname="") { - $this->firstName = $firstname; + if ($firstname) + { + $index = count($this->words); + $this->words[$index] = new NCLNameCaseWord($firstname); + $this->words[$index]->setNamePart('N'); + $this->notReady(); + } } /* @@ -340,7 +249,13 @@ class NCLNameCaseCore extends NCL public function setSecondName($secondname="") { - $this->secondName = $secondname; + if ($secondname) + { + $index = count($this->words); + $this->words[$index] = new NCLNameCaseWord($secondname); + $this->words[$index]->setNamePart('S'); + $this->notReady(); + } } /* @@ -353,7 +268,13 @@ class NCLNameCaseCore extends NCL public function setFatherName($fathername="") { - $this->fatherName = $fathername; + if ($fathername) + { + $index = count($this->words); + $this->words[$index] = new NCLNameCaseWord($fathername); + $this->words[$index]->setNamePart('F'); + $this->notReady(); + } } /* @@ -368,7 +289,10 @@ class NCLNameCaseCore extends NCL public function setGender($gender=0) { - $this->gender = $gender; + foreach ($this->words as $word) + { + $word->setTrueGender($gender); + } } /* @@ -427,6 +351,96 @@ class NCLNameCaseCore extends NCL $this->setSecondName($secondname); } + protected function prepareNamePart(NCLNameCaseWord $word) + { + if (!$word->getNamePart()) + { + $this->detectNamePart($word); + } + } + + protected function prepareAllNameParts() + { + foreach ($this->words as $word) + { + $this->prepareNamePart($word); + } + } + + protected function prepareGender(NCLNameCaseWord $word) + { + if (!$word->isGenderSolved()) + { + $namePart = $word->getNamePart(); + switch ($namePart) + { + case 'N': $this->GenderByFirstName($word); + break; + case 'F': $this->GenderByFatherName($word); + break; + case 'S': $this->GenderBySecondName($word); + break; + } + } + } + + protected function solveGender() + { + //Ищем, может гдето пол уже установлен + foreach ($this->words as $word) + { + if ($word->isGenderSolved()) + { + $this->setGender($word->gender()); + return true; + } + } + + //Если нет тогда определяем у каждого слова и потом сумируем + $man = 0; + $woman = 0; + + foreach ($this->words as $word) + { + $this->prepareGender($word); + $gender = $word->getGender(); + $man+=$gender[NCL::$MAN]; + $woman+=$gender[NCL::$WOMAN]; + } + + if ($man > $woman) + { + $this->setGender(NCL::$MAN); + } + else + { + $this->setGender(NCL::$WOMAN); + } + + return true; + } + + protected function generateIndex() + { + $this->index = array('N' => array(), 'S' => array(), 'F' => array()); + foreach ($this->words as $index => $word) + { + $namepart = $word->getNamePart(); + $this->index[$namepart][] = $index; + } + } + + protected function prepareEverything() + { + if (!$this->ready) + { + $this->prepareAllNameParts(); + $this->solveGender(); + $this->generateIndex(); + $this->ready = true; + } + } + /* * Автоматическое определение пола * Возвращает пол по ФИО @@ -435,9 +449,12 @@ class NCLNameCaseCore extends NCL public function genderAutoDetect() { - $this->gender = null; - $this->genderDetect(); - return $this->gender; + $this->prepareEverything(); + if (isset($this->words[0])) + { + return $this->words[0]->gender(); + } + return false; } /* @@ -447,137 +464,120 @@ class NCLNameCaseCore extends NCL public function splitFullName($fullname) { - $this->firstName = ''; - $this->secondName = ''; - $this->fatherName = ''; - $this->gender = null; $fullname = trim($fullname); $list = explode(' ', $fullname); - $found = array(); - $duplicate = array(); - $c = count($list); - for ($i = 0; $i < $c; $i++) + + foreach ($list as $word) { - if (trim($list[$i])) - { - $found[$i][0] = $this->detectNamePart($list[$i]); - $found[$i][1] = $list[$i]; - if ($found[$i][0] == 'N') - { - $this->firstName = $found[$i][1]; - } - elseif ($found[$i][0] == 'S') - { - $this->secondName = $found[$i][1]; - } - elseif ($found[$i][0] == 'F') - { - $this->fatherName = $found[$i][1]; - } - } + $this->words[] = new NCLNameCaseWord($word); } - $format = array(); - foreach ($found as $value) + $this->prepareEverything(); + $formatArr = array(); + + foreach ($this->words as $word) { - $format[] = $value; + $formatArr[] = $word->getNamePart(); } - if (count($format) == 1) + + return implode(' ', $formatArr); + } + + protected function WordCase(NCLNameCaseWord $word) + { + $gender = ($word->gender() == NCL::$MAN ? 'man' : 'woman'); + + $namepart = ''; + + switch ($word->getNamePart()) { - return $format[0][0]; + case 'F': $namepart = 'Father'; break; + case 'N': $namepart = 'First'; break; + case 'S': $namepart = 'Second'; break; + } + + $method = $gender . $namepart . 'Name'; + + $this->setWorkingWord($word->getWord()); + + if ($this->$method()) + { + $word->setNameCases($this->lastResult); + $word->setRule($this->lastRule); } else { - return $format; + $word->setNameCases(array_fill(0, $this->CaseCount, $word->getWord())); + $word->setRule(-1); } } - /* - * Склонение имени - * - * @return boolean - */ - - protected function FirstName() + protected function AllWordCases() { - $this->genderDetect(); - if ($this->firstName) + if (!$this->finished) { - if ($this->gender == 1) + $this->prepareEverything(); + + foreach ($this->words as $word) { - $result = $this->manFirstName(); + $this->WordCase($word); } - else - { - $result = $this->womanFirstName(); - } - $this->firstResult[0] = $this->firstName; - return $result; - } - else - { - $this->firstResult = array_fill(0, $this->CaseCount, ""); - return false; + + $this->finished = true; } } - /* - * Склонение фамилии - * - * @return boolean - */ - - protected function SecondName() + private function getWordCase(NCLNameCaseWord $word, $number=null) { - $this->genderDetect(); - if ($this->secondName) + $cases = $word->getNameCases(); + if (is_null($number) or $number < 0 or $number > ($this->CaseCount - 1)) { - if ($this->gender == 1) - { - $result = $this->manSecondName(); - } - else - { - $result = $this->womanSecondName(); - } - $this->secondResult[0] = $this->secondName; - return $result; + return $cases; } else { - $this->secondResult = array_fill(0, $this->CaseCount, ""); - return false; + return $cases[$number]; } } - /* - * Склонение отчеств - * - * @return boolean + /** + * Возвращает склееные результаты склонения + * @param array $indexArray - индексы слов, которые необходимо склеить + * @param int $number - */ - - protected function FatherName() + private function getCasesConnected($indexArray, $number=null) { - $this->genderDetect(); - if ($this->fatherName) + $readyArr = array(); + foreach ($indexArray as $index) { - if ($this->gender == 1) + $readyArr[] = $this->getWordCase($this->words[$index], $number); + } + + $all = count($readyArr); + if ($all) + { + if (is_array($readyArr[0])) { - $result = $this->manFatherName(); + //Масив нужно скелить каждый падеж + $resultArr = array(); + for ($case = 0; $case < $this->CaseCount; $case++) + { + $tmp = array(); + for ($i = 0; $i < $all; $i++) + { + $tmp[] = $readyArr[$i][$case]; + } + $resultArr[$case] = implode(' ', $tmp); + } + return $resultArr; } else { - $result = $this->womanFatherName(); + return implode(' ', $readyArr); } - $this->fatherResult[0] = $this->fatherName; - return $result; - } - else - { - $this->fatherResult = array_fill(0, $this->CaseCount, ""); - return false; } + return ''; } /* @@ -588,24 +588,9 @@ class NCLNameCaseCore extends NCL public function getFirstNameCase($number=null) { - if (!isset($this->firstResult[0]) or $this->firstResult[0] <> $this->firstName) - { - $this->FirstName(); - } - if ($number < 0 or $number > ($this->CaseCount - 1)) - { - $number = null; - } + $this->AllWordCases(); - if (is_null($number)) - { - //Возвращаем все падежи - return $this->firstResult; - } - else - { - return $this->firstResult[$number]; - } + return $this->getCasesConnected($this->index['N'], $number); } /* @@ -616,24 +601,9 @@ class NCLNameCaseCore extends NCL public function getSecondNameCase($number=null) { - if (!isset($this->secondResult[0]) or $this->secondResult[0] <> $this->secondName) - { - $this->SecondName(); - } - if ($number < 0 or $number > ($this->CaseCount - 1)) - { - $number = null; - } + $this->AllWordCases(); - if (is_null($number)) - { - //Возвращаем все падежи - return $this->secondResult; - } - else - { - return $this->secondResult[$number]; - } + return $this->getCasesConnected($this->index['S'], $number); } /* @@ -644,24 +614,9 @@ class NCLNameCaseCore extends NCL public function getFatherNameCase($number=null) { - if (!isset($this->fatherResult[0]) or $this->fatherResult[0] <> $this->fatherName) - { - $this->FatherName(); - } - if ($number < 0 or $number > ($this->CaseCount - 1)) - { - $number = null; - } + $this->AllWordCases(); - if (is_null($number)) - { - //Возвращаем все падежи - return $this->fatherResult; - } - else - { - return $this->fatherResult[$number]; - } + return $this->getCasesConnected($this->index['F'], $number); } /* @@ -672,8 +627,12 @@ class NCLNameCaseCore extends NCL public function qFirstName($firstName, $CaseNumber=null, $gender=0) { - $this->gender = $gender; - $this->firstName = $firstName; + $this->fullReset(); + $this->setFirstName($firstName); + if ($gender) + { + $this->setGender($gender); + } return $this->getFirstNameCase($CaseNumber); } @@ -685,8 +644,13 @@ class NCLNameCaseCore extends NCL public function qSecondName($secondName, $CaseNumber=null, $gender=0) { - $this->gender = $gender; - $this->secondName = $secondName; + $this->fullReset(); + $this->setSecondName($secondName); + if ($gender) + { + $this->setGender($gender); + } + return $this->getSecondNameCase($CaseNumber); } @@ -698,8 +662,12 @@ class NCLNameCaseCore extends NCL public function qFatherName($fatherName, $CaseNumber=null, $gender=0) { - $this->gender = $gender; - $this->fatherName = $fatherName; + $this->fullReset(); + $this->setFatherName($fatherName); + if ($gender) + { + $this->setGender($gender); + } return $this->getFatherNameCase($CaseNumber); } @@ -719,12 +687,13 @@ class NCLNameCaseCore extends NCL { return $this->getFormattedArrayHard($format); } - $length = mb_strlen($format); + + $length = NCLStr::strlen($format); $result = array(); $cases = array(); for ($i = 0; $i < $length; $i++) { - $symbol = mb_substr($format, $i, 1); + $symbol = NCLStr::substr($format, $i, 1); if ($symbol == 'S') { $cases['S'] = $this->getSecondNameCase(); @@ -744,7 +713,7 @@ class NCLNameCaseCore extends NCL $line = ""; for ($i = 0; $i < $length; $i++) { - $symbol = mb_substr($format, $i, 1); + $symbol = NCLStr::substr($format, $i, 1); if ($symbol == 'S') { $line.=$cases['S'][$curCase]; @@ -857,7 +826,7 @@ class NCLNameCaseCore extends NCL public function getFormatted($caseNum=0, $format="S N F") { - //Если не указан формат используем другую функцию + //Если не указан падеж используем другую функцию if (is_null($caseNum)) { return $this->getFormattedArray($format); @@ -869,11 +838,11 @@ class NCLNameCaseCore extends NCL } else { - $length = mb_strlen($format); + $length = NCLStr::strlen($format); $result = ""; for ($i = 0; $i < $length; $i++) { - $symbol = mb_substr($format, $i, 1); + $symbol = NCLStr::substr($format, $i, 1); if ($symbol == 'S') { $result.=$this->getSecondNameCase($caseNum); @@ -907,24 +876,18 @@ class NCLNameCaseCore extends NCL public function qFullName($secondName="", $firstName="", $fatherName="", $gender=0, $caseNum=0, $format="S N F") { - $this->gender = $gender; - $this->firstName = $firstName; - $this->secondName = $secondName; - $this->fatherName = $fatherName; + $this->fullReset(); + $this->setFirstName($firstName); + $this->setSecondName($secondName); + $this->setFatherName($fatherName); + if ($gender) + { + $this->setGender($gender); + } return $this->getFormatted($caseNum, $format); } - public function getFirstNameRule() - { - return $this->frule; - } - - public function getSecondNameRule() - { - return $this->srule; - } - /* * Быстрое склонение имени. Передается один параметр строка, где может быть ФИО в любом виде. Есть необязательный параметр пол. И так ще необязательный параметр падеж. Если падеж указан, тогда возвращается строка в том падеже, если нет тогда все возможные падежи. * @@ -933,9 +896,12 @@ class NCLNameCaseCore extends NCL public function q($fullname, $caseNum=null, $gender=null) { + $this->fullReset(); $format = $this->splitFullName($fullname); - $this->gender = $gender; - $this->genderAutoDetect(); + if ($gender) + { + $this->setGender($gender); + } return $this->getFormatted($caseNum, $format); } diff --git a/Library/NCL/NCLNameCaseInterface.php b/Library/NCL/NCLNameCaseInterface.php index ddc4be5..1003eb2 100644 --- a/Library/NCL/NCLNameCaseInterface.php +++ b/Library/NCL/NCLNameCaseInterface.php @@ -45,10 +45,6 @@ interface NCLNameCaseInterface public function qFullName($secondName="", $firstName="", $fatherName="", $gender=0, $caseNum=0, $format="S N F"); - public function getFirstNameRule(); - - public function getSecondNameRule(); - public function q($fullname, $caseNum=null, $gender=null); } diff --git a/Library/NCL/NCLNameCaseWord.php b/Library/NCL/NCLNameCaseWord.php index 3b1b661..924cb4e 100644 --- a/Library/NCL/NCLNameCaseWord.php +++ b/Library/NCL/NCLNameCaseWord.php @@ -1,4 +1,5 @@ core = $core; - + $this->generateMask($word); + $this->word = NCLStr::strtolower($word); + } + + private function generateMask($word) + { + $letters = NCLStr::splitLetters($word); + $mask = array(); + $this->isUpperCase = true; + foreach ($letters as $letter) + { + if (NCLStr::isLowerCase($letter)) + { + $mask[] = 'x'; + $this->isUpperCase = false; + } + else + { + $mask[] = 'X'; + } + } + $this->letterMask = $mask; + } + + private function returnMask() + { + if ($this->isUpperCase) + { + foreach ($this->NameCases as $index => $case) + { + $this->NameCases[$index] = NCLStr::strtoupper($this->NameCases[$index]); + } + } + else + { + $splitedMask = $this->letterMask; + $maskLength = count($splitedMask); + foreach ($this->NameCases as $index => $case) + { + $caseLength = NCLStr::strlen($case); + + $max = min(array($caseLength, $maskLength)); + $this->NameCases[$index] = ''; + for ($letterIndex = 0; $letterIndex < $max; $letterIndex++) + { + $letter = NCLStr::substr($case, $letterIndex, 1); + if ($splitedMask[$letterIndex] == 'X') + { + $letter = NCLStr::strtoupper($letter); + } + $this->NameCases[$index] .= $letter; + } + $this->NameCases[$index] .= NCLStr::substr($case, $max, $caseLength-$maskLength); + } + } + } + + public function setNameCases($nameCases) + { + $this->NameCases = $nameCases; + $this->returnMask(); + } + + public function getNameCases() + { + return $this->NameCases; + } + + public function gender() + { + if (!$this->genderSolved) + { + if ($this->genderMan > $this->genderWoman) + { + $this->genderSolved = NCL::$MAN; + } + else + { + $this->genderSolved = NCL::$WOMAN; + } + } + return $this->genderSolved; + } + + public function setGender($man, $woman) + { + $this->genderMan = $man; + $this->genderWoman = $woman; + } + + public function setTrueGender($gender) + { + $this->genderSolved = $gender; + } + + public function getGender() + { + return array(NCL::$MAN => $this->genderMan, NCL::$WOMAN => $this->genderWoman); + } + + public function setNamePart($namePart) + { + $this->namePart = $namePart; + } + + public function getNamePart() + { + return $this->namePart; + } + + public function getWord() + { + return $this->word; + } + + public function isGenderSolved() + { + return ($this->genderSolved ? true : false); + } + + public function setRule($ruleID) + { + $this->rule = $ruleID; } } - ?> diff --git a/Library/NCL/NCLStr.php b/Library/NCL/NCLStr.php index df949f9..6efc4d7 100644 --- a/Library/NCL/NCLStr.php +++ b/Library/NCL/NCLStr.php @@ -72,6 +72,11 @@ class NCLStr { return ($phrase == NCLStr::strtolower($phrase)); } + + static function isUpperCase($phrase) + { + return ($phrase == NCLStr::strtoupper($phrase)); + } static function splitLetters($phrase) { @@ -84,6 +89,11 @@ class NCLStr return $resultArr; } + static function connectLetters($lettersArr) + { + return implode('', $lettersArr); + } + static function explode($pattern, $string) { return mb_split($pattern, $string); diff --git a/Tests/debug.php b/Tests/debug.php index 1f70945..cd7ea80 100644 --- a/Tests/debug.php +++ b/Tests/debug.php @@ -3,6 +3,6 @@ header('Content-type: text/html; charset=utf-8'); require '../Library/NCL.NameCase.ua.php'; $ob = new NCLNameCaseUa; -print_r($ob->qSecondName('Сорока',null,2)); +print_r($ob->qFirstName('Ялина',null,2)); echo $ob->getSecondNameRule(); ?>