i18n.php 4.93 KB
Newer Older
1
2
3
4
5
6
7
<?php
/**
 * This software is governed by the CeCILL-B license. If a copy of this license
 * is not distributed with this file, you can obtain one at
 * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.txt
 *
 * Authors of STUdS (initial project): Guilhem BORGHESI (borghesi@unistra.fr) and Raphaël DROZ
8
 * Authors of Framadate/OpenSondage: Framasoft (https://github.com/framasoft)
9
10
11
12
13
14
15
16
17
18
19
 *
 * =============================
 *
 * Ce logiciel est régi par la licence CeCILL-B. Si une copie de cette licence
 * ne se trouve pas avec ce fichier vous pouvez l'obtenir sur
 * http://www.cecill.info/licences/Licence_CeCILL-B_V1-fr.txt
 *
 * Auteurs de STUdS (projet initial) : Guilhem BORGHESI (borghesi@unistra.fr) et Raphaël DROZ
 * Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft)
 */

20
21
22
23
24
25
26
const DATE_FORMAT_FULL = 'EEEE d MMMM y';
const DATE_FORMAT_SHORT = 'EEEE d MMMM y';
const DATE_FORMAT_DAY = 'E d';
const DATE_FORMAT_DATE = 'dd-MM-y';
const DATE_FORMAT_MONTH_YEAR = 'MMMM y';
const DATE_FORMAT_DATETIME_SHORT = 'EEEE d';

27
// Change session language when requested
28
if (isset($_REQUEST['lang'])
29
    && array_key_exists($_REQUEST['lang'], $ALLOWED_LANGUAGES)) {
30
31
32
    $_SESSION['lang'] = $_REQUEST['lang'];
}

33
34
35
36
// Try the user-specified locale, or the browser-specified locale.
if (isset($_SESSION['lang'])) {
    $wanted_locale = $_SESSION['lang'];
} else  {
37
    $http_lang = $_SERVER['HTTP_ACCEPT_LANGUAGE'] ?? DEFAULT_LANGUAGE;
Thomas Citharel's avatar
Thomas Citharel committed
38
    $wanted_locale = Locale::acceptFromHttp($http_lang);
39
40
}
// Use the best available locale.
Thomas Citharel's avatar
Thomas Citharel committed
41
$locale = Locale::lookup(array_keys($ALLOWED_LANGUAGES), $wanted_locale, false, DEFAULT_LANGUAGE);
42

43
44
45
/**
 * Formats a DateTime according to the IntlDateFormatter
 *
46
 * @param DateTime|null $date
47
48
 * @param string $pattern
 * @param $forceLocale
49
 * @throws Exception
50
51
 * @return string
 */
52
function date_format_intl(?DateTime $date, $pattern = DATE_FORMAT_FULL, $forceLocale = null) {
53
    global $locale;
54
55
    $local_locale = $forceLocale ?? $locale;
    $date = $date ?? new DateTime();
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75

    $dateFormatter = IntlDateFormatter::create(
        $local_locale,
        IntlDateFormatter::FULL,
        IntlDateFormatter::FULL,
        date_default_timezone_get(),
        IntlDateFormatter::GREGORIAN,
        $pattern
    );
    return $dateFormatter->format($date);
}

/**
 * Formats a DateTime according to a translated format
 *
 * @param DateTime $date
 * @param string $pattern
 * @return string
 */
function date_format_translation(DateTime $date, $pattern = 'Y-m-d') {
76
    return $date->format(t('Date', $pattern));
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
}

/**
 * Converts a string into a DateTime according to the IntlDateFormatter
 *
 * @param $dateString
 * @param string $pattern
 * @param string|null $forceLocale
 * @return DateTime|null
 */
function parse_intl_date($dateString, $pattern = DATE_FORMAT_DATE, $forceLocale = null) {
    global $locale;
    $local_locale = $forceLocale || $locale;

    $dateFormatter = IntlDateFormatter::create(
        $local_locale,
        IntlDateFormatter::FULL,
        IntlDateFormatter::FULL,
        date_default_timezone_get(),
        IntlDateFormatter::GREGORIAN,
        $pattern
    );
    $timestamp = $dateFormatter->parse($dateString);
    try {
        return (new DateTime())->setTimestamp($timestamp);
    } catch (Exception $e) {
        return null;
    }
}

/**
 * Converts a string into a DateTime according to a translated format
 *
 * @param string $dateString
 * @param string $pattern
 * @return DateTime
 */
function parse_translation_date($dateString, $pattern = 'Y-m-d') {
115
    return DateTime::createFromFormat(t('Date', $pattern), $dateString);
116
117
}

118
119
120
121
122
/* i18n helper functions */
use Symfony\Component\Translation\Loader\PoFileLoader;
use Symfony\Component\Translation\Translator;

class __i18n {
Thomas Citharel's avatar
Thomas Citharel committed
123
    /* @var Translator */
124
    private static $translator;
Thomas Citharel's avatar
Thomas Citharel committed
125
    /* @var Translator */
126
    private static $fallbacktranslator;
127

128
129
    public static function init($locale) {
        self::$translator = new Translator($locale);
130
        self::$translator->addLoader('pofile', new PoFileLoader());
131
        self::$translator->addResource('pofile', ROOT_DIR . "po/{$locale}.po", $locale);
132
133
134
135
136
137
138
        # Fallback:
        # For Symfony/Translation, empty strings are valid, but in po files, untranslated strings are "".
        # This means we cannot use the standard $translator->setFallbackLocales() mechanism :(
        self::$fallbacktranslator = new Translator(DEFAULT_LANGUAGE);
        self::$fallbacktranslator->addLoader('pofile', new PoFileLoader());
        self::$fallbacktranslator->addResource('pofile', ROOT_DIR . "po/" . DEFAULT_LANGUAGE . ".po", DEFAULT_LANGUAGE);
    }
139

140
141
142
143
    public static function translate($key) {
        return self::$translator->trans($key)
            ?: self::$fallbacktranslator->trans($key);
    }
144
}
145
__i18n::init($locale);
146

147
function t($section, $key) {
148
149
150
    return __i18n::translate($key);
}

151
function n($section, $key, $args) {
152
153
154
155
    $msg = __i18n::translate($key);
    $args = array_slice(func_get_args(), 2);
    return vsprintf($msg, $args);
}