summaryrefslogtreecommitdiff
path: root/includes/language.inc
blob: e997efa3710d25b87a3436c9c64233abf9917142 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
<?php
// $Id$

/**
 * @file
 * Multiple language handling functionality.
 */

/**
 *  Choose a language for the page, based on language negotiation settings.
 */
function language_initialize() {
  global $user;

  $mode = variable_get('language_negotiation', LANGUAGE_NEGOTIATION_NONE);
  switch ($mode) {
    case LANGUAGE_NEGOTIATION_NONE:
      return language_default();

    case LANGUAGE_NEGOTIATION_DOMAIN:
      $languages = language_list();
      foreach ($languages as $language) {
        $parts = parse_url($language->domain);
        if (!empty($parts['host']) && ($_SERVER['SERVER_NAME'] == $parts['host'])) {
          return $language;
        }
      }
      return language_default();

    case LANGUAGE_NEGOTIATION_PATH_DEFAULT:
    case LANGUAGE_NEGOTIATION_PATH:
      $languages = language_list('prefix');
      // $_GET['q'] might not be available at this time, because
      // path initialization runs after the language bootstrap phase.
      $args = isset($_GET['q']) ? explode('/', $_GET['q']) : array();
      $language = array_shift($args);
      if (isset($languages[$language])) {
        // Rebuild $GET['q'] with the language removed.
        $_GET['q'] = implode('/', $args);
        return $languages[$language];
      }
      elseif ($mode == LANGUAGE_NEGOTIATION_PATH_DEFAULT) {
        return language_default();
      }
      break;
  }

  // User language.
  $languages = language_list();
  if ($user->uid && isset($languages[$user->language])) {
    return $languages[$user->language];
  }

  // Browser accept-language parsing.
  if ($language = language_from_browser()) {
    return $language;
  }

  // Fall back on the default if everything else fails.
  return language_default();
}

/**
 * Identify language from the Accept-language HTTP header we got.
 */
function language_from_browser() {
  // Specified by the user via the browser's Accept Language setting
  // Samples: "hu, en-us;q=0.66, en;q=0.33", "hu,en-us;q=0.5"
  $browser_langs = array();

  if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
    $browser_accept = explode(",", $_SERVER['HTTP_ACCEPT_LANGUAGE']);
    for ($i = 0; $i < count($browser_accept); $i++) {
      // The language part is either a code or a code with a quality.
      // We cannot do anything with a * code, so it is skipped.
      // If the quality is missing, it is assumed to be 1 according to the RFC.
      if (preg_match("!([a-z-]+)(;q=([0-9\\.]+))?!", trim($browser_accept[$i]), $found)) {
        $browser_langs[$found[1]] = (isset($found[3]) ? (float) $found[3] : 1.0);
      }
    }
  }

  // Order the codes by quality
  arsort($browser_langs);

  // Try to find the first preferred language we have
  $languages = language_list('enabled');
  foreach ($browser_langs as $langcode => $q) {
    if (isset($languages['1'][$langcode])) {
      return $languages['1'][$langcode];
    }
  }
}

/**
 * Rewrite URL's with language based prefix. Parameters are the same
 * as those of the url() function.
 */
function language_url_rewrite(&$path, &$options) {
  global $language;

  // Only modify relative (insite) URLs.
  if (!$options['external']) {

    // Language can be passed as an option, or we go for current language.
    if (!isset($options['language'])) {
      $options['language'] = $language;
    }

    switch (variable_get('language_negotiation', LANGUAGE_NEGOTIATION_NONE)) {
      case LANGUAGE_NEGOTIATION_NONE:
        // No language dependent path allowed in this mode.
        unset($options['language']);
        break;

      case LANGUAGE_NEGOTIATION_DOMAIN:
        if ($options['language']->domain) {
          // Ask for an absolute URL with our modified base_url.
          $options['absolute'] = TRUE;
          $options['base_url'] = $options['language']->domain;
        }
        break;

      case LANGUAGE_NEGOTIATION_PATH_DEFAULT:
        $default = language_default();
        if ($options['language']->language == $default->language) {
          break;
        }
        // Intentionally no break here.

      case LANGUAGE_NEGOTIATION_PATH:
        if (!empty($options['language']->prefix)) {
          $options['prefix'] = $options['language']->prefix .'/';
        }
        break;
    }
  }
}