Skip to content

Instantly share code, notes, and snippets.

@neonxp
Created October 22, 2013 12:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save neonxp/7100118 to your computer and use it in GitHub Desktop.
Save neonxp/7100118 to your computer and use it in GitHub Desktop.
<?php
/**
* @author Alexander Kiryukhin <alexander@symdev.org>
* @date: 22.10.13
* @time: 16:39
*/
class NameCases
{
const SEX_MALE = 0; // Мужской пол
const SEX_FEMALE = 1; // Женский пол
const SEX_UNISEX = 2; // Любой пол (только в правилах, не для setSex() !)
const CASE_NOMINATIVE = 0; // Именительный
const CASE_GENITIVE = 1; // Родительный
const CASE_DATIVE = 2; // Дательный
const CASE_ACCUSATIVE = 3; // Винительный
const CASE_INSTRUMENTAL = 4; // Творительный
const CASE_PREPOSITIONAL = 5; // Предложный
private $rules = [
[
'sex' => self::SEX_UNISEX,
'test' => [
'дюма',
'тома',
'дега',
'люка',
'ферма',
'гамарра',
'петипа',
'гусь',
'ремень',
'камень',
'онук',
'богода',
'нечипас',
'долгопалец',
'маненок',
'рева',
'кива'
],
'mods' => ['.', '.', '.', '.', '.']
],
[
'sex' => self::SEX_UNISEX,
'test' => ['вий', 'сой', 'цой', 'хой'],
'mods' => ['-я', '-ю', '-я', '-ем', '-е']
],
[
'sex' => self::SEX_FEMALE,
'test' => [
'рашель',
'нинель',
'николь',
'габриэль',
'даниэль',
'иволга',
'герцен',
'блок',
'бах',
'врубель',
'хемингуэй',
'гайдай'
],
'mods' => ['.', '.', '.', '.', '.']
],
[
'sex' => self::SEX_UNISEX,
'test' => ['в', 'н'],
'mods' => ['а', 'у', 'а', 'ым', 'е']
],
[
'sex' => self::SEX_FEMALE,
'test' => [
'б',
'в',
'г',
'д',
'ж',
'з',
'й',
'к',
'л',
'м',
'н',
'п',
'р',
'с',
'т',
'ф',
'х',
'ц',
'ч',
'ш',
'щ',
'ъ',
'ь'
],
'mods' => ['.', '.', '.', '.', '.']
],
[
'sex' => self::SEX_FEMALE,
'test' => ['ска', 'цка'],
'mods' => ['-ой', '-ой', '-ую', '-ой', '-ой']
],
[
'sex' => self::SEX_FEMALE,
'test' => ['ая'],
'mods' => ['--ой', '--ой', '--ую', '--ой', '--ой']
],
[
'sex' => self::SEX_UNISEX,
'test' => ['ская'],
'mods' => ['--ой', '--ой', '--ую', '--ой', '--ой']
],
[
'sex' => self::SEX_FEMALE,
'test' => ['на'],
'mods' => ['-у', '-ой', '-у', '-ой', '-ой']
],
[
'sex' => self::SEX_UNISEX,
'test' => ['иной'],
'mods' => ['-я', '-ю', '-я', '-ем', '-е']
],
[
'sex' => self::SEX_UNISEX,
'test' => ['уй'],
'mods' => ['-я', '-ю', '-я', '-ем', '-е']
],
[
'sex' => self::SEX_UNISEX,
'test' => ['ца'],
'mods' => ['-ы', '-е', '-у', '-ей', '-е']
],
[
'sex' => self::SEX_UNISEX,
'test' => ['рих'],
'mods' => ['а', 'у', 'а', 'ом', 'е']
],
[
'sex' => self::SEX_UNISEX,
'test' => ['ия'],
'mods' => ['.', '.', '.', '.', '.']
],
[
'sex' => self::SEX_UNISEX,
'test' => ['иа', 'аа', 'оа', 'уа', 'ыа', 'еа', 'юа', 'эа'],
'mods' => ['.', '.', '.', '.', '.']
],
[
'sex' => self::SEX_UNISEX,
'test' => ['их', 'ых'],
'mods' => ['.', '.', '.', '.', '.']
],
[
'sex' => self::SEX_UNISEX,
'test' => ['о', 'е', 'э', 'и', 'ы', 'у', 'ю'],
'mods' => ['.', '.', '.', '.', '.']
],
[
'sex' => self::SEX_UNISEX,
'test' => ['ова', 'ева'],
'mods' => ['-ой', '-ой', '-у', '-ой', '-ой']
],
[
'sex' => self::SEX_UNISEX,
'test' => ['га', 'ка', 'ха', 'ча', 'ща', 'жа'],
'mods' => ['-и', '-е', '-у', '-ой', '-е']
],
[
'sex' => self::SEX_UNISEX,
'test' => ['ца'],
'mods' => ['-и', '-е', '-у', '-ей', '-е']
],
[
'sex' => self::SEX_UNISEX,
'test' => ['а'],
'mods' => ['-ы', '-е', '-у', '-ой', '-е']
],
[
'sex' => self::SEX_UNISEX,
'test' => ['ь'],
'mods' => ['-я', '-ю', '-я', '-ем', '-е']
],
[
'sex' => self::SEX_UNISEX,
'test' => ['ия'],
'mods' => ['-и', '-и', '-ю', '-ей', '-и']
],
[
'sex' => self::SEX_UNISEX,
'test' => ['я'],
'mods' => ['-и', '-е', '-ю', '-ей', '-е']
],
[
'sex' => self::SEX_UNISEX,
'test' => ['ей'],
'mods' => ['-я', '-ю', '-я', '-ем', '-е']
],
[
'sex' => self::SEX_UNISEX,
'test' => ['ян', 'ан', 'йн'],
'mods' => ['а', 'у', 'а', 'ом', 'е']
],
[
'sex' => self::SEX_UNISEX,
'test' => ['ынец', 'обец'],
'mods' => ['--ца', '--цу', '--ца', '--цем', '--це']
],
[
'sex' => self::SEX_UNISEX,
'test' => ['онец', 'овец'],
'mods' => ['--ца', '--цу', '--ца', '--цом', '--це']
],
[
'sex' => self::SEX_UNISEX,
'test' => ['ц', 'ч', 'ш', 'щ'],
'mods' => ['а', 'у', 'а', 'ем', 'е']
],
[
'sex' => self::SEX_UNISEX,
'test' => ['ай'],
'mods' => ['-я', '-ю', '-я', '-ем', '-е']
],
[
'sex' => self::SEX_UNISEX,
'test' => ['ой'],
'mods' => ['-го', '-му', '-го', '--им', '-м']
],
[
'sex' => self::SEX_UNISEX,
'test' => ['ах', 'ив'],
'mods' => ['а', 'у', 'а', 'ом', 'е']
],
[
'sex' => self::SEX_UNISEX,
'test' => ['ший', 'щий', 'жий', 'ний'],
'mods' => ['--его', '--ему', '--его', '-м', '--ем']
],
[
'sex' => self::SEX_UNISEX,
'test' => ['кий', 'ый'],
'mods' => ['--ого', '--ому', '--ого', '-м', '--ом']
],
[
'sex' => self::SEX_UNISEX,
'test' => ['ий'],
'mods' => ['-я', '-ю', '-я', '-ем', '-и']
],
[
'sex' => self::SEX_UNISEX,
'test' => ['ок'],
'mods' => ['--ка', '--ку', '--ка', '--ком', '--ке']
],
[
'sex' => self::SEX_UNISEX,
'test' => ['ец'],
'mods' => ['--ца', '--цу', '--ца', '--цом', '--це']
],
[
'sex' => self::SEX_UNISEX,
'test' => ['б', 'г', 'д', 'ж', 'з', 'к', 'л', 'м', 'п', 'р', 'с', 'т', 'ф', 'х'],
'mods' => ['а', 'у', 'а', 'ом', 'е']
],
[
'sex' => self::SEX_UNISEX,
'test' => ['лев'],
'mods' => ['--ьва', '--ьву', '--ьва', '--ьвом', '--ьве']
],
[
'sex' => self::SEX_UNISEX,
'test' => ['павел'],
'mods' => ['--ла', '--лу', '--ла', '--лом', '--ле']
],
[
'sex' => self::SEX_MALE,
'test' => ['шота'],
'mods' => ['.', '.', '.', '.', '.']
],
[
'sex' => self::SEX_UNISEX,
'test' => ['е', 'ё', 'и', 'о', 'у', 'ы', 'э', 'ю'],
'mods' => ['.', '.', '.', '.', '.']
],
[
'sex' => self::SEX_FEMALE,
'test' => [
'б',
'в',
'г',
'д',
'ж',
'з',
'й',
'к',
'л',
'м',
'н',
'п',
'р',
'с',
'т',
'ф',
'х',
'ц',
'ч',
'ш',
'щ',
'ъ'
],
'mods' => ['.', '.', '.', '.', '.']
],
[
'sex' => self::SEX_FEMALE,
'test' => ['ь'],
'mods' => ['-и', '-и', '.', 'ю', '-и']
],
[
'sex' => self::SEX_MALE,
'test' => ['ь'],
'mods' => ['-я', '-ю', '-я', '-ем', '-е']
],
[
'sex' => self::SEX_UNISEX,
'test' => ['га', 'ка', 'ха', 'ча', 'ща', 'жа'],
'mods' => ['-и', '-е', '-у', '-ой', '-е']
],
[
'sex' => self::SEX_UNISEX,
'test' => ['а'],
'mods' => ['-ы', '-е', '-у', '-ой', '-е']
],
[
'sex' => self::SEX_UNISEX,
'test' => ['ия'],
'mods' => ['-и', '-и', '-ю', '-ей', '-и']
],
[
'sex' => self::SEX_UNISEX,
'test' => ['я'],
'mods' => ['-и', '-е', '-ю', '-ей', '-е']
],
[
'sex' => self::SEX_UNISEX,
'test' => ['ей'],
'mods' => ['-я', '-ю', '-я', '-ем', '-е']
],
[
'sex' => self::SEX_UNISEX,
'test' => ['ий'],
'mods' => ['-я', '-ю', '-я', '-ем', '-и']
],
[
'sex' => self::SEX_UNISEX,
'test' => ['й'],
'mods' => ['-я', '-ю', '-я', '-ем', '-е']
],
[
'sex' => self::SEX_UNISEX,
'test' => ['б', 'в', 'г', 'д', 'ж', 'з', 'к', 'л', 'м', 'н', 'п', 'р', 'с', 'т', 'ф', 'х', 'ц', 'ч'],
'mods' => ['а', 'у', 'а', 'ом', 'е']
]
];
/**
* @var string
*/
protected $firstName;
/**
* @var string
*/
protected $lastName;
/**
* @var string
*/
protected $middleName;
/**
* @var int
*/
protected $sex;
public function getFirstName($case = self::CASE_NOMINATIVE)
{
return $this->mbUcFirst($this->wordToCase($this->firstName, $case));
}
public function setFirstName($firstName)
{
$this->firstName = mb_strtolower($firstName, 'utf8');
}
public function getLastName($case = self::CASE_NOMINATIVE)
{
return $this->mbUcFirst($this->wordToCase($this->lastName, $case));
}
public function setLastName($lastName)
{
$this->lastName = mb_strtolower($lastName, 'utf8');
}
public function getMiddleName($case = self::CASE_NOMINATIVE)
{
return $this->mbUcFirst($this->wordToCase($this->middleName, $case));
}
public function setMiddleName($middleName)
{
$this->middleName = mb_strtolower($middleName, 'utf8');
}
public function getSex()
{
return $this->sex;
}
public function setSex($sex)
{
$this->sex = $sex;
}
private function wordToCase($word, $case)
{
if ($case !== self::CASE_NOMINATIVE) {
foreach ($this->rules as $rule) { //Идём по правилам
$tests = $rule['test'];
foreach ($tests as $test) { //Берем все проверки конкретного правила
$ending = mb_substr(
$word,
(mb_strlen($word, 'utf8') - mb_strlen($test, 'utf8')),
mb_strlen($test, 'utf8'),
'utf8'
); // Получаем соответствующее окончание
if (
(($rule['sex'] === self::SEX_UNISEX) ||
($rule['sex'] === $this->getSex()))
&& (mb_strtolower($ending, 'utf8') === $test)
) {
//Правило подходит, применяем его
$suffix = $rule['mods'][$case - 1];
$adding = '';
for ($i = 0; $i < mb_strlen($suffix); $i++) {
$char = mb_substr($suffix, $i, 1, 'utf8');
switch ($char) {
case '.':
break;
case '-':
$word = mb_substr($word, 0, (mb_strlen($word, 'utf8') - 1), 'utf8');
break;
default:
$adding .= $char;
}
}
return ($word . $adding);
}
}
}
}
return $word;
}
private function mbUcFirst($word)
{
return mb_strtoupper(mb_substr($word, 0, 1, 'utf8')) . mb_strtolower(mb_substr($word, 1, null, 'utf8'));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment