138 lines
3.6 KiB
PHP
138 lines
3.6 KiB
PHP
<?php
|
|
|
|
enum DeclensionCase: string {
|
|
case GEN = 'Gen';
|
|
case DAT = 'Dat';
|
|
case ACC = 'Acc';
|
|
case INS = 'Ins';
|
|
case ABL = 'Abl';
|
|
}
|
|
|
|
enum NameSex: int {
|
|
case MALE = 0;
|
|
case FEMALE = 1;
|
|
}
|
|
|
|
enum NameType: int {
|
|
case FIRST_NAME = 0;
|
|
case LAST_NAME = 1;
|
|
}
|
|
|
|
class StringsBase implements ArrayAccess {
|
|
protected array $data = [];
|
|
|
|
public function offsetSet(mixed $offset, mixed $value): void {
|
|
throw new RuntimeException('Not implemented');
|
|
}
|
|
|
|
public function offsetExists(mixed $offset): bool {
|
|
return isset($this->data[$offset]);
|
|
}
|
|
|
|
public function offsetUnset(mixed $offset): void {
|
|
throw new RuntimeException('Not implemented');
|
|
}
|
|
|
|
public function offsetGet(mixed $offset): mixed {
|
|
if (!isset($this->data[$offset])) {
|
|
logError(__METHOD__.': '.$offset.' not found');
|
|
return '{'.$offset.'}';
|
|
}
|
|
return $this->data[$offset];
|
|
}
|
|
|
|
public function get(string $key, mixed ...$sprintf_args): string|array {
|
|
$val = $this[$key];
|
|
if (!empty($sprintf_args)) {
|
|
array_unshift($sprintf_args, $val);
|
|
return call_user_func_array('sprintf', $sprintf_args);
|
|
} else {
|
|
return $val;
|
|
}
|
|
}
|
|
|
|
public function num(string $key, int $num, array$opts = []) {
|
|
$s = $this[$key];
|
|
|
|
$default_opts = [
|
|
'format' => true,
|
|
'format_delim' => ' ',
|
|
'lang' => 'ru',
|
|
];
|
|
$opts = array_merge($default_opts, $opts);
|
|
|
|
switch ($opts['lang']) {
|
|
case 'ru':
|
|
$n = $num % 100;
|
|
if ($n > 19)
|
|
$n %= 10;
|
|
|
|
if ($n == 1) {
|
|
$word = 0;
|
|
} elseif ($n >= 2 && $n <= 4) {
|
|
$word = 1;
|
|
} elseif ($num == 0 && count($s) == 4) {
|
|
$word = 3;
|
|
} else {
|
|
$word = 2;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
if ($num == 0 && count($s) == 4) {
|
|
$word = 3;
|
|
} else {
|
|
$word = $num == 1 ? 0 : 1;
|
|
}
|
|
break;
|
|
}
|
|
|
|
// if zero
|
|
if ($word == 3) {
|
|
return $s[3];
|
|
}
|
|
|
|
if (is_callable($opts['format'])) {
|
|
$num = $opts['format']($num);
|
|
} else if ($opts['format'] === true) {
|
|
$num = formatNumber($num, $opts['format_delim']);
|
|
}
|
|
|
|
return sprintf($s[$word], $num);
|
|
}
|
|
}
|
|
|
|
class Strings extends StringsBase {
|
|
private static ?Strings $instance = null;
|
|
protected array $loadedPackages = [];
|
|
|
|
private function __construct() {}
|
|
protected function __clone() {}
|
|
|
|
public static function getInstance(): self {
|
|
if (is_null(self::$instance))
|
|
self::$instance = new self();
|
|
return self::$instance;
|
|
}
|
|
|
|
public function load(string ...$pkgs): array {
|
|
$keys = [];
|
|
foreach ($pkgs as $name) {
|
|
$raw = yaml_parse_file(APP_ROOT.'/strings/'.$name.'.yaml');
|
|
$this->data = array_merge($this->data, $raw);
|
|
$keys = array_merge($keys, array_keys($raw));
|
|
$this->loadedPackages[$name] = true;
|
|
}
|
|
return $keys;
|
|
}
|
|
|
|
public function flex(string $s, DeclensionCase $case, NameSex $sex, NameType $type): string {
|
|
$s = iconv('utf-8', 'cp1251', $s);
|
|
$s = vkflex($s, $case->value, $sex->value, 0, $type->value);
|
|
return iconv('cp1251', 'utf-8', $s);
|
|
}
|
|
|
|
public function search(string $regexp): array {
|
|
return preg_grep($regexp, array_keys($this->data));
|
|
}
|
|
} |