/[drupal]/drupal/includes/language.inc
ViewVC logotype

Contents of /drupal/includes/language.inc

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.23 - (show annotations) (download) (as text)
Sat Oct 24 05:13:43 2009 UTC (5 weeks, 1 day ago) by webchick
Branch: MAIN
CVS Tags: DRUPAL-7-0-UNSTABLE-10, HEAD
Changes since 1.22: +1 -42 lines
File MIME type: text/x-php
#320331 by Dave Reid, dww, John Morahan, cwgordon7, moshe weitzman, c960657, and smoothify: Turn custom_url_rewrite_inbound() and custom_url_rewrite_outbound() into hooks.
1 <?php
2 // $Id: language.inc,v 1.22 2009/10/16 15:47:46 webchick Exp $
3
4 /**
5 * @file
6 * Multiple language handling functionality.
7 */
8
9 /**
10 * No language negotiation. The default language is used.
11 */
12 define('LANGUAGE_NEGOTIATION_DEFAULT', 'language-default');
13
14 /**
15 * Return all the defined language types.
16 *
17 * @return
18 * An array of language type names. The name will be used as the global
19 * variable name the language value will be stored in.
20 */
21 function language_types_info() {
22 $language_types = &drupal_static(__FUNCTION__);
23
24 if (!isset($language_types)) {
25 $language_types = module_invoke_all('language_types_info');
26 // Let other modules alter the list of language types.
27 drupal_alter('language_types_info', $language_types);
28 }
29
30 return $language_types;
31 }
32
33 /**
34 * Return only the configurable language types.
35 *
36 * A language type maybe configurable or fixed. A fixed language type is a type
37 * whose negotiation values are unchangable and defined while defining the
38 * language type itself.
39 *
40 * @return
41 * An array of language type names.
42 */
43 function language_types_configurable() {
44 $configurable = &drupal_static(__FUNCTION__);
45
46 if (!isset($configurable)) {
47 $types = variable_get('language_types', drupal_language_types());
48 $configurable = array_keys(array_filter($types));
49 }
50
51 return $configurable;
52 }
53
54 /**
55 * Disable the given language types.
56 *
57 * @param $types
58 * An array of language types.
59 */
60 function language_types_disable($types) {
61 $enabled_types = variable_get('language_types', drupal_language_types());
62
63 foreach ($types as $type) {
64 unset($enabled_types[$type]);
65 }
66
67 variable_set('language_types', $enabled_types);
68 }
69
70 /**
71 * Check if a language provider is enabled.
72 *
73 * This has two possible behaviors:
74 * - If $provider_id is given return its ID if enabled, FALSE otherwise.
75 * - If no ID is passed the first enabled language provider is returned.
76 *
77 * @param $type
78 * The language negotiation type.
79 * @param $provider_id
80 * The language provider ID.
81 *
82 * @return
83 * The provider ID if it is enabled, FALSE otherwise.
84 */
85 function language_negotiation_get($type, $provider_id = NULL) {
86 $negotiation = variable_get("language_negotiation_$type", array());
87
88 if (empty($negotiation)) {
89 return empty($provider_id) ? LANGUAGE_NEGOTIATION_DEFAULT : FALSE;
90 }
91
92 if (empty($provider_id)) {
93 return key($negotiation);
94 }
95
96 if (isset($negotiation[$provider_id])) {
97 return $provider_id;
98 }
99
100 return FALSE;
101 }
102
103 /**
104 * Check if the given language provider is enabled for any configurable language
105 * type.
106 *
107 * @param $provider_id
108 * The language provider ID.
109 *
110 * @return
111 * TRUE if there is at least one language type for which the give language
112 * provider is enabled, FALSE otherwise.
113 */
114 function language_negotiation_get_any($provider_id) {
115 foreach (language_types_configurable() as $type) {
116 if (language_negotiation_get($type, $provider_id)) {
117 return TRUE;
118 }
119 }
120
121 return FALSE;
122 }
123
124 /**
125 * Return the language switch links for the given language.
126 *
127 * @param $type
128 * The language negotiation type.
129 * @param $path
130 * The internal path the switch links will be relative to.
131 *
132 * @return
133 * A keyed array of links ready to be themed.
134 */
135 function language_negotiation_get_switch_links($type, $path) {
136 $links = FALSE;
137 $negotiation = variable_get("language_negotiation_$type", array());
138
139 foreach ($negotiation as $id => $provider) {
140 if (isset($provider['callbacks']['switcher'])) {
141 if (isset($provider['file'])) {
142 require_once DRUPAL_ROOT . '/' . $provider['file'];
143 }
144
145 $callback = $provider['callbacks']['switcher'];
146 $result = $callback($type, $path);
147
148 if (!empty($result)) {
149 // Allow modules to provide translations for specific links.
150 drupal_alter('language_switch_links', $result, $type, $path);
151 $links = (object) array('links' => $result, 'provider' => $id);
152 break;
153 }
154 }
155 }
156
157 return $links;
158 }
159
160
161 /**
162 * Save a list of language providers.
163 *
164 * @param $type
165 * The language negotiation type.
166 * @param $language_providers
167 * An array of language provider ids.
168 */
169 function language_negotiation_set($type, $language_providers) {
170 // Save only the necessary fields.
171 $provider_fields = array('callbacks', 'file', 'cache');
172
173 $negotiation = array();
174 $providers_weight = array();
175 $defined_providers = language_negotiation_info();
176 $default_types = language_types_configurable();
177
178 // Initialize the providers weight list.
179 foreach ($language_providers as $id => $provider) {
180 $providers_weight[$id] = language_provider_weight($provider);
181 }
182
183 // Order providers list by weight.
184 asort($providers_weight);
185
186 foreach ($providers_weight as $id => $weight) {
187 if (isset($defined_providers[$id])) {
188 $provider = $defined_providers[$id];
189 // If the provider does not express any preference about types, make it
190 // available for any configurable type.
191 $types = array_flip(isset($provider['types']) ? $provider['types'] : $default_types);
192 // Check if the provider is defined and has the right type.
193 if (isset($types[$type])) {
194 $provider_data = array();
195 foreach ($provider_fields as $field) {
196 if (isset($provider[$field])) {
197 $provider_data[$field] = $provider[$field];
198 }
199 }
200 $negotiation[$id] = $provider_data;
201 }
202 }
203 }
204
205 variable_set("language_negotiation_$type", $negotiation);
206 }
207
208 /**
209 * Return all the defined language providers.
210 *
211 * @return
212 * An array of language providers.
213 */
214 function language_negotiation_info() {
215 $language_providers = &drupal_static(__FUNCTION__);
216
217 if (!isset($language_providers)) {
218 // Collect all the module-defined language negotiation providers.
219 $language_providers = module_invoke_all('language_negotiation_info');
220
221 // Add the default language provider.
222 $language_providers[LANGUAGE_NEGOTIATION_DEFAULT] = array(
223 'callbacks' => array('language' => 'language_from_default'),
224 'weight' => 10,
225 'name' => t('Default'),
226 'description' => t('The default site language (@language_name) is used.', array('@language_name' => language_default()->native)),
227 );
228
229 // Let other modules alter the list of language providers.
230 drupal_alter('language_negotiation_info', $language_providers);
231 }
232
233 return $language_providers;
234 }
235
236 /**
237 * Helper function used to cache the language providers results.
238 *
239 * @param $provider_id
240 * The language provider ID.
241 * @param $provider
242 * The language provider to be invoked. If not passed it will be explicitly
243 * loaded through language_negotiation_info().
244 *
245 * @return
246 * The language provider's return value.
247 */
248 function language_provider_invoke($provider_id, $provider = NULL) {
249 $results = &drupal_static(__FUNCTION__);
250
251 if (!isset($results[$provider_id])) {
252 global $user;
253
254 // Get languages grouped by status and select only the enabled ones.
255 $languages = language_list('enabled');
256 $languages = $languages[1];
257
258 if (!isset($provider)) {
259 $providers = language_negotiation_info();
260 $provider = $providers[$provider_id];
261 }
262
263 if (isset($provider['file'])) {
264 require_once DRUPAL_ROOT . '/' . $provider['file'];
265 }
266
267 // If the language provider has no cache preference or this is satisified
268 // we can execute the callback.
269 $cache = !isset($provider['cache']) || $user->uid || $provider['cache'] == variable_get('cache', CACHE_DISABLED);
270 $callback = isset($provider['callbacks']['language']) ? $provider['callbacks']['language'] : FALSE;
271 $langcode = $cache && function_exists($callback) ? $callback($languages) : FALSE;
272 $results[$provider_id] = isset($languages[$langcode]) ? $languages[$langcode] : FALSE;
273 }
274
275 return $results[$provider_id];
276 }
277
278 /**
279 * Return the passed language provider weight or a default value.
280 *
281 * @param $provider
282 * A language provider data structure.
283 *
284 * @return
285 * A numeric weight.
286 */
287 function language_provider_weight($provider) {
288 $default = is_numeric($provider) ? $provider : 0;
289 return isset($provider['weight']) && is_numeric($provider['weight']) ? $provider['weight'] : $default;
290 }
291
292 /**
293 * Choose a language for the given type based on language negotiation settings.
294 *
295 * @param $type
296 * The language type.
297 *
298 * @return
299 * The negotiated language object.
300 */
301 function language_initialize($type) {
302 // Execute the language providers in the order they were set up and return the
303 // first valid language found.
304 $negotiation = variable_get("language_negotiation_$type", array());
305
306 foreach ($negotiation as $id => $provider) {
307 $language = language_provider_invoke($id, $provider);
308 if ($language) {
309 return $language;
310 }
311 }
312
313 // If no other language was found use the default one.
314 return language_default();
315 }
316
317 /**
318 * Default language provider.
319 *
320 * @return
321 * The default language code.
322 */
323 function language_from_default() {
324 return language_default()->language;
325 }
326
327 /**
328 * Split the given path into prefix and actual path.
329 *
330 * Parse the given path and return the language object identified by the
331 * prefix and the actual path.
332 *
333 * @param $path
334 * The path to split.
335 * @param $languages
336 * An array of valid languages.
337 *
338 * @return
339 * An array composed of:
340 * - A language object corresponding to the identified prefix on success,
341 * FALSE otherwise.
342 * - The path without the prefix on success, the given path otherwise.
343 */
344 function language_url_split_prefix($path, $languages) {
345 $args = empty($path) ? array() : explode('/', $path);
346 $prefix = array_shift($args);
347
348 // Search prefix within enabled languages.
349 foreach ($languages as $language) {
350 if (!empty($language->prefix) && $language->prefix == $prefix) {
351 // Rebuild $path with the language removed.
352 return array($language, implode('/', $args));
353 }
354 }
355
356 return array(FALSE, $path);
357 }
358
359 /**
360 * Return the possible fallback languages ordered by language weight.
361 *
362 * @param
363 * The language type.
364 *
365 * @return
366 * An array of language codes.
367 */
368 function language_fallback_get_candidates($type = LANGUAGE_TYPE_CONTENT) {
369 $fallback_candidates = &drupal_static(__FUNCTION__);
370
371 if (!isset($fallback_candidates)) {
372 $fallback_candidates = array();
373
374 // Get languages ordered by weight.
375 // Use array keys to avoid duplicated entries.
376 foreach (language_list('weight') as $languages) {
377 foreach ($languages as $language) {
378 $fallback_candidates[$language->language] = NULL;
379 }
380 }
381
382 $fallback_candidates = array_keys($fallback_candidates);
383 $fallback_candidates[] = FIELD_LANGUAGE_NONE;
384
385 // Let other modules hook in and add/change candidates.
386 drupal_alter('language_fallback_candidates', $fallback_candidates);
387 }
388
389 return $fallback_candidates;
390 }

  ViewVC Help
Powered by ViewVC 1.1.2