summaryrefslogtreecommitdiff
path: root/engine/strings.php
diff options
context:
space:
mode:
authorEvgeny Zinoviev <me@ch1p.io>2024-01-31 06:11:00 +0300
committerEvgeny Zinoviev <me@ch1p.io>2024-01-31 20:45:40 +0300
commitc0dc531ebefd8912819f3b6c8bda1fed3c7e750c (patch)
tree2c75aa9df182260aef09faf4befd81a4c2b9c5e2 /engine/strings.php
parent48d688cdf7f9eae1bf11b8a6f0e5b98687c604cb (diff)
make it simple, but not simpler
Diffstat (limited to 'engine/strings.php')
-rw-r--r--engine/strings.php138
1 files changed, 138 insertions, 0 deletions
diff --git a/engine/strings.php b/engine/strings.php
new file mode 100644
index 0000000..2d9b1d3
--- /dev/null
+++ b/engine/strings.php
@@ -0,0 +1,138 @@
+<?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 = [];
+
+ function offsetSet(mixed $offset, mixed $value): void {
+ throw new RuntimeException('Not implemented');
+ }
+
+ function offsetExists(mixed $offset): bool {
+ return isset($this->data[$offset]);
+ }
+
+ function offsetUnset(mixed $offset): void {
+ throw new RuntimeException('Not implemented');
+ }
+
+ function offsetGet(mixed $offset): mixed {
+ if (!isset($this->data[$offset])) {
+ logError(__METHOD__.': '.$offset.' not found');
+ return '{'.$offset.'}';
+ }
+ return $this->data[$offset];
+ }
+
+ 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;
+ }
+ }
+
+ 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;
+ }
+
+ 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;
+ }
+
+ 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);
+ }
+
+ function search(string $regexp): array {
+ return preg_grep($regexp, array_keys($this->data));
+ }
+} \ No newline at end of file