1<?php
2
3/**
4 * DokuWiki Plugin reqlang (Action Component)
5 *
6 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
7 * @author  Andreas Gohr <andi@splitbrain.org>
8 */
9class action_plugin_reqlang extends \dokuwiki\Extension\ActionPlugin
10{
11
12    /** @inheritDoc */
13    public function register(Doku_Event_Handler $controller)
14    {
15        $controller->register_hook('INIT_LANG_LOAD', 'BEFORE', $this, 'handleLangLoading');
16
17    }
18
19    /**
20     * Initialize the correct language
21     *
22     * @param Doku_Event $event event object by reference
23     * @param mixed $param optional parameter passed when event was registered
24     * @return void
25     */
26    public function handleLangLoading(Doku_Event $event, $param)
27    {
28        global $INPUT;
29        global $conf;
30
31        $langs = $this->parseAcceptLang($INPUT->server->str('HTTP_ACCEPT_LANGUAGE'));
32        $langs[] = $conf['lang']; // add fallback to default at the end
33
34        foreach ($langs as $lang) {
35            if (is_dir(DOKU_INC . 'inc/lang/' . $lang)) {
36                $conf['lang'] = $lang;
37                $event->data = $lang;
38                return;
39            }
40        }
41    }
42
43    /**
44     * This returns the list of wanted languages in the correct order
45     *
46     * @param string $header
47     * @return string[]
48     */
49    public function parseAcceptLang($header)
50    {
51        $header = strtolower($header);
52        preg_match_all('/([a-z]{1,8}(-[a-z]{1,8})?)\s*(;\s*q\s*=\s*(1|0\.[0-9]+))?/i', $header, $lang_parse);
53        if (!count($lang_parse[1])) return [];
54
55        // create a list like "en" => 0.8
56        $langs = array_combine($lang_parse[1], $lang_parse[4]);
57
58        // set default to 1 for any without q factor
59        foreach ($langs as $lang => $prio) {
60            if ($prio === '') $langs[$lang] = 1;
61        }
62
63        // add primary language if missing
64        foreach ($langs as $lang => $prio) {
65            $split = strpos($lang, '-');
66            if ($split !== false) {
67                $primary = substr($lang, 0, $split);
68                if (!isset($langs[$primary])) {
69                    $langs[$primary] = $prio - 0.01;
70                }
71            }
72        }
73
74        // sort list based on value
75        arsort($langs, SORT_NUMERIC);
76
77        return array_unique(array_keys($langs));
78    }
79}
80
81