diff --git a/app/Core/Func.php b/app/Core/Func.php index 5c058e28..ea5986c2 100644 --- a/app/Core/Func.php +++ b/app/Core/Func.php @@ -24,6 +24,12 @@ class Func */ protected $langs; + /** + * Список имен доступных языков + * @var array + */ + protected $nameLangs; + /** * Конструктор * @@ -41,10 +47,8 @@ class Func */ public function getStyles() { - if (empty($this->styles)) { - $this->styles = \array_map(function($style) { - return \str_replace([$this->c->DIR_PUBLIC . '/style/', '/style.css'], '', $style); - }, \glob($this->c->DIR_PUBLIC . '/style/*/style.css')); + if (! \is_array($this->styles)) { + $this->styles = $this->getFoldersWithFile($this->c->DIR_PUBLIC . '/style', 'style.css'); } return $this->styles; } @@ -56,14 +60,58 @@ class Func */ public function getLangs() { - if (empty($this->langs)) { - $this->langs = \array_map(function($lang) { - return \str_replace([$this->c->DIR_LANG . '/', '/common.po'], '', $lang); - }, \glob($this->c->DIR_LANG . '/*/common.po')); + if (! \is_array($this->langs)) { + $this->langs = $this->getFoldersWithFile($this->c->DIR_LANG, 'common.po'); } return $this->langs; } + /** + * Список имен доступных языков + * + * @return array + */ + public function getNameLangs() + { + if (! \is_array($this->nameLangs)) { + $langs = $this->getLangs(); + foreach ($langs as &$value) { + $value = include "{$this->c->DIR_LANG}/{$value}/name.php"; + } + unset($value); + $this->nameLangs = $langs; + } + + return $this->nameLangs; + } + + /** + * Список папок в данной директории содержащих заданный файл + * + * @param string $dir + * @param string $file + * + * @return array + */ + public function getFoldersWithFile($dir, $file) + { + $result = []; + if (\is_dir($dir) && ($dh = \opendir($dir)) !== false) { + while (($entry = \readdir($dh)) !== false) { + if (isset($entry{0}) + && $entry{0} !== '.' + && \is_dir("{$dir}/{$entry}") + && \is_file("{$dir}/{$entry}/{$file}") + ) { + $result[$entry] = $entry; + } + } + \closedir($dh); + \asort($result, \SORT_NATURAL); + } + return $result; + } + /** * Пагинация * @@ -117,4 +165,38 @@ class Func } return $pages; } + + /** + * Разбор HTTP_ACCEPT_LANGUAGE + * + * @param string $str + * + * @return array + */ + public function langParse($str) + { + $result = []; + + foreach (\explode(',', $str) as $step) { + $dsr = \explode(';', $step, 2); + if (isset($dsr[1])) { + $q = \trim(\ltrim(\ltrim($dsr[1], 'q '), '=')); + if (! \is_numeric($q) || $q < 0 || $q > 1) { + continue; + } + $q = (float) $q; + } else { + $q = 1; + } + + $l = \trim($dsr[0]); + if (! \preg_match('%^[[:alpha:]]{1,8}(?:-[[:alnum:]]{1,8})?$%', $l)) { + continue; + } + + $result[$l] = $q; + } + + return \array_keys(\arsort($result, \SORT_NUMERIC)); + } } diff --git a/app/Models/Pages/Admin/Options.php b/app/Models/Pages/Admin/Options.php index 19d3f7f6..319031d4 100644 --- a/app/Models/Pages/Admin/Options.php +++ b/app/Models/Pages/Admin/Options.php @@ -202,10 +202,8 @@ class Options extends Admin ]; $yn = [1 => \ForkBB\__('Yes'), 0 => \ForkBB\__('No')]; - $langs = $this->c->Func->getLangs(); - $langs = \array_combine($langs, $langs); + $langs = $this->c->Func->getNameLangs(); $styles = $this->c->Func->getStyles(); - $styles = \array_combine($styles, $styles); $form['sets']['essentials'] = [ 'legend' => \ForkBB\__('Essentials subhead'), diff --git a/app/Models/Pages/Install.php b/app/Models/Pages/Install.php index dab527c7..a8be11d0 100644 --- a/app/Models/Pages/Install.php +++ b/app/Models/Pages/Install.php @@ -115,7 +115,7 @@ class Install extends Page unset($config); // языки - $langs = $this->c->Func->getLangs(); + $langs = $this->c->Func->getNameLangs(); if (empty($langs)) { $this->fIswev = ['e', \ForkBB\__('No language packs')]; } @@ -183,7 +183,7 @@ class Install extends Page 'fields' => [ 'installlang' => [ 'type' => 'select', - 'options' => \array_combine($langs, $langs), + 'options' => $langs, 'value' => $this->user->language, 'caption' => \ForkBB\__('Install language'), 'info' => \ForkBB\__('Choose install language info'), @@ -345,14 +345,14 @@ class Install extends Page ], 'defaultlang' => [ 'type' => 'select', - 'options' => \array_combine($langs, $langs), + 'options' => $langs, 'value' => $v ? $v->defaultlang : $this->user->language, 'caption' => \ForkBB\__('Default language'), 'required' => true, ], 'defaultstyle' => [ 'type' => 'select', - 'options' => \array_combine($styles, $styles), + 'options' => $styles, 'value' => $v ? $v->defaultstyle : $this->user->style, 'caption' => \ForkBB\__('Default style'), 'required' => true, diff --git a/app/Models/Pages/Profile/Config.php b/app/Models/Pages/Profile/Config.php index 2f59a109..d87fb436 100644 --- a/app/Models/Pages/Profile/Config.php +++ b/app/Models/Pages/Profile/Config.php @@ -108,10 +108,8 @@ class Config extends Profile ]; $yn = [1 => \ForkBB\__('Yes'), 0 => \ForkBB\__('No')]; - $langs = $this->c->Func->getLangs(); - $langs = \array_combine($langs, $langs); + $langs = $this->c->Func->getNameLangs(); $styles = $this->c->Func->getStyles(); - $styles = \array_combine($styles, $styles); $timeFormat = []; foreach ($this->c->TIME_FORMATS as $key => $value) { $timeFormat[$key] = \ForkBB\dt(\time(), false, null, $value, true, true) . ($key ? '' : ' (' . \ForkBB\__('Default') . ')'); diff --git a/app/lang/English/name.php b/app/lang/English/name.php new file mode 100644 index 00000000..a9e3cbf1 --- /dev/null +++ b/app/lang/English/name.php @@ -0,0 +1,3 @@ +