#53 - Class for localization

Data: 2019-03-23 12:00 - PHP

PHP class that parses headers for localization (l10n) and provides text translations from json files.

<?php
class Language {
    private static $default_language = 'en-GB';

    private static $directory = null;
    private static $languages = array();

    private static $current_language = null;
    private static $language_data = null;

    public static function initialize($directory, $languages, $default_language) {
        self::$directory = $directory;
        self::$languages = $languages;
        self::$default_language = $default_language;
    }

    public static function getCurrentLanguage() {
        if (self::$current_language == null) {
            static::$current_language = static::$default_language;
            if (AuthToken::hasCookie() || Session::hasSession()) {
                static::$current_language = Session::getLanguage();
                if (static::$current_language === null || !file_exists(self::$directory . '/' . static::$current_language .'.json'))
                    static::$current_language = static::$default_language;
            } else if ((!Session::isInitialized() || Session::getLanguage() == null) && isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
                $ordered_langs = array();
                $http_langs = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']);
                foreach ($http_langs as $lg) {
                    $lang_and_q = explode(';q=', $lg);
                    if (!array_key_exists(1, $lang_and_q)) {
                        $lang_and_q[1] = 1.0;
                    }
                    $ordered_langs[$lang_and_q[0]] = $lang_and_q[1];
                }
                arsort($ordered_langs);

                foreach ($ordered_langs as $lg => $q) {
                    if (array_key_exists($lg, static::$languages)) {
                        static::$current_language = $lg;
                        break;
                    }

                    $sub_lang = explode('-', $lg);
                    if (count($sub_lang) == 1) {
                        $got_lang = false;
                        foreach (static::$languages as $avaliable_lang => $void) {
                            if (strpos($avaliable_lang, $lg . '-') === 0) {
                                static::$current_language = $avaliable_lang;
                                $got_lang = true;
                                break;
                            }
                        }
                        if ($got_lang)
                            break;
                    }

                    if (array_key_exists($sub_lang[0], static::$languages)) {
                        static::$current_language = $sub_lang[0];
                        // using a sublang, but keep searching...
                    }
                }
            }
        }

        return self::$current_language;
    }

    public static function setLanguage($new_language) {
        $new_lang = trim($new_language);
        $ok = preg_match('/([a-z]{2})([A-Z]{2})?/', $new_lang);

        if ($ok && file_exists(self::$directory . '/' . $new_lang . '.json')) {
            Session::setLanguage($new_lang);
            static::$current_language = $new_lang;
        }
    }

    public static function buildCurrentIcon($languages_images_dir, $class_list = '') {
        $lang_ext = self::$languages[self::getCurrentLanguage()];
        echo '<a title="',  $lang_ext, '" href="?lang=', self::getCurrentLanguage(), '"', (!empty($class_list) ? (' class="' . $class_list . '"') : ''),'><img src="', $languages_images_dir, self::getCurrentLanguage(), '.png"></a>';
    }

    private static function buildIcon($title, $href, $class, $img) {
        echo '<a title="', $title, '" href="', $href, '"', (!empty($class) ? (' class="' . $class . '"') : ''),'><img src="', $img, '"></a>';
    }

    public static function buildIconList($languages_images_dir, $options) {
        $current_lang = static::getCurrentLanguage();
        $current_ext = null;
        foreach (static::$languages as $lang => $lang_ext) {
            if ($lang == $current_lang) {
                $current_ext = $lang_ext;
                if (isset($options['current_last']) && $options['current_last'] === true)
                    continue;
                $current_options = isset($options['current']) ? $options['current'] : [];
                $url = isset($current_options['url']) ? $current_options['url'] : ('?lang=' . $lang);
                $class = isset($current_options['class']) ? $current_options['class'] : '';
                self::buildIcon($lang_ext, $url, $class, $languages_images_dir . $lang . '.png');
            } else
                self::buildIcon($lang_ext, '?lang=' . $lang, '', $languages_images_dir . $lang . '.png');
        }

        if (isset($options['current_last']) && $options['current_last'] === true) {
            $current_options = isset($options['current']) ? $options['current'] : [];
            $url = isset($current_options['url']) ? $current_options['url'] : ('?lang=' . $current_lang);
            $class = isset($current_options['class']) ? $current_options['class'] : '';
            self::buildIcon($current_ext, $url, $class, $languages_images_dir . $current_lang . '.png');
        }
    }

    private static function initLanguage() {
        static::$language_data = json_decode(file_get_contents(self::$directory . '/' . static::getCurrentLanguage() .'.json'), true);
    }

    public static function _($str, ...$args) {
        if (static::$language_data == null)
            static::initLanguage();
        return array_key_exists($str, static::$language_data) ? sprintf(static::$language_data[$str], ...$args) : $str;
    }

    public static function _page($page, $args) {
        if (static::$language_data == null)
            static::initLanguage();
        $file = self::$directory . '/pages/' . $page . '.' . static::getCurrentLanguage() . '.html';
        if (!file_exists($file))
            return $page;
        $content = file_get_contents($file);
        foreach ($args as $key => $value) {
            $content = str_replace('{{' . $key . '}}', $value, $content);
        }
        return $content;
    }
}

function _($str, ...$args) {
    return Language::_($str, ...$args);
}

function _page($page, $args) {
    return Language::_page($page, $args);
}

Previous snippet | Next snippet