1 |
85ad3d82
|
Assos Assos
|
<?php
|
2 |
|
|
|
3 |
|
|
/**
|
4 |
|
|
* @file
|
5 |
|
|
* Internationalization (i18n) package - translatable strings reusable admin UI.
|
6 |
|
|
*
|
7 |
|
|
* @author Jose A. Reyero, 2007
|
8 |
|
|
*/
|
9 |
|
|
|
10 |
|
|
// Load locale libraries
|
11 |
|
|
include_once DRUPAL_ROOT . '/includes/locale.inc';
|
12 |
|
|
include_once drupal_get_path('module', 'locale') . '/locale.admin.inc';
|
13 |
|
|
|
14 |
|
|
/**
|
15 |
|
|
* Generate translate page from object.
|
16 |
|
|
*
|
17 |
|
|
* @param string $object_type
|
18 |
|
|
* Obejct type as declared in hook_i18n_object_info().
|
19 |
|
|
* @param object $object_value
|
20 |
|
|
* Drupal object to translate.
|
21 |
|
|
* @param object $language
|
22 |
|
|
* Optional language object.
|
23 |
|
|
*/
|
24 |
|
|
function i18n_string_translate_page_object($object_type, $object_value, $language = NULL) {
|
25 |
|
|
// For backwards compatibility, ensure parameter is a language object
|
26 |
|
|
$language = i18n_language_object($language);
|
27 |
|
|
$langcode = $language ? $language->language : NULL;
|
28 |
|
|
// Get base keys for all these strings. Object key may be multiple like for blocks (module, delta)
|
29 |
|
|
$object = i18n_object($object_type, $object_value);
|
30 |
|
|
$strings = $object->get_strings(array('empty' => TRUE));
|
31 |
|
|
|
32 |
|
|
// If no localizable strings, print message and fail gracefully.
|
33 |
|
|
// Possibly this object comes from some other contrib module.
|
34 |
|
|
// See http://drupal.org/node/1889878
|
35 |
|
|
if (!$strings) {
|
36 |
|
|
return t('This object has no strings available for translation.');
|
37 |
|
|
}
|
38 |
|
|
|
39 |
|
|
if (empty($langcode)) {
|
40 |
|
|
drupal_set_title(t('Translate !name', array('!name' => i18n_object_info($object_type, 'title'))));
|
41 |
|
|
return i18n_string_translate_page_overview($object, $strings);
|
42 |
|
|
}
|
43 |
|
|
else {
|
44 |
|
|
drupal_set_title(t('Translate to !language', array('!language' => i18n_language_name($langcode))));
|
45 |
|
|
return drupal_get_form('i18n_string_translate_page_form', $strings, $langcode);
|
46 |
|
|
}
|
47 |
|
|
}
|
48 |
|
|
|
49 |
|
|
/**
|
50 |
|
|
* Provide a core translation module like overview page for this object.
|
51 |
|
|
*/
|
52 |
|
|
function i18n_string_translate_page_overview($object, $strings) {
|
53 |
|
|
$build['i18n_overview'] = drupal_get_form('i18n_string_translate_page_overview_form', $object, $strings);
|
54 |
|
|
return $build;
|
55 |
|
|
}
|
56 |
|
|
|
57 |
|
|
/**
|
58 |
|
|
* Provide a core translation module like overview page for this object.
|
59 |
|
|
*/
|
60 |
|
|
function i18n_string_translate_page_overview_form($form, &$form_state, $object, $strings) {
|
61 |
|
|
// Set the default item key, assume it's the first.
|
62 |
|
|
$item_title = reset($strings);
|
63 |
|
|
$header = array(
|
64 |
|
|
'language' => t('Language'),
|
65 |
|
|
'title' => t('Title'),
|
66 |
|
|
'status' => t('Status'),
|
67 |
|
|
'operations' => t('Operations')
|
68 |
|
|
);
|
69 |
|
|
$source_language = variable_get_value('i18n_string_source_language');
|
70 |
|
|
$rows = array();
|
71 |
|
|
|
72 |
|
|
foreach (language_list() as $langcode => $language) {
|
73 |
|
|
if ($langcode == $source_language) {
|
74 |
|
|
$items = array(
|
75 |
|
|
'language' => check_plain($language->name) . ' ' . t('(source)'),
|
76 |
|
|
'title' => check_plain($item_title->get_string()),
|
77 |
|
|
'status' => t('original'),
|
78 |
|
|
'operations' => l(t('edit'), $object->get_edit_path()),
|
79 |
|
|
);
|
80 |
|
|
}
|
81 |
|
|
else {
|
82 |
|
|
// Try to figure out if this item has any of its properties translated.
|
83 |
|
|
$translated = FALSE;
|
84 |
|
|
foreach ($strings as $i18nstring) {
|
85 |
|
|
if ($i18nstring->get_translation($langcode)) {
|
86 |
|
|
$translated = TRUE;
|
87 |
|
|
break;
|
88 |
|
|
}
|
89 |
|
|
}
|
90 |
|
|
// Translate the item that was requested to be displayed as title.
|
91 |
|
|
$items = array(
|
92 |
|
|
'language' => check_plain($language->name),
|
93 |
|
|
'title' => $item_title->format_translation($langcode, array('sanitize default' => TRUE)),
|
94 |
|
|
'status' => $translated ? t('translated') : t('not translated'),
|
95 |
|
|
'operations' => l(t('translate'), $object->get_translate_path($langcode), array('query' => drupal_get_destination())),
|
96 |
|
|
);
|
97 |
|
|
}
|
98 |
|
|
foreach ($items as $key => $markup) {
|
99 |
|
|
$rows[$langcode][$key] = $markup;
|
100 |
|
|
//$form['#rows'][$langcode][$key]['#markup'] = $markup;
|
101 |
|
|
}
|
102 |
|
|
}
|
103 |
|
|
// Build a form so it can be altered later, with all this information.
|
104 |
|
|
$form['object'] = array('#type' => 'value', '#value' => $object);
|
105 |
|
|
$form['source_language'] = array('#type' => 'value', '#value' => $source_language);
|
106 |
|
|
$form['languages'] = array(
|
107 |
|
|
'#header' => $header,
|
108 |
|
|
'#rows' => $rows,
|
109 |
|
|
'#theme' => 'table',
|
110 |
|
|
);
|
111 |
|
|
return $form;
|
112 |
|
|
}
|
113 |
|
|
|
114 |
|
|
/**
|
115 |
|
|
* Form builder callback for in-place string translation.
|
116 |
|
|
*
|
117 |
|
|
* @param $strings
|
118 |
|
|
* Array of strings indexed by string name (may be indexed by group key too if $groups is present)
|
119 |
|
|
* @param $langcode
|
120 |
|
|
* Language code to translate to.
|
121 |
|
|
* @param $groups
|
122 |
|
|
* Optional groups to provide some string grouping. Array with group key and title pairs.
|
123 |
|
|
*/
|
124 |
|
|
function i18n_string_translate_page_form($form, &$form_state, $strings, $langcode, $groups = NULL) {
|
125 |
|
|
$form = i18n_string_translate_page_form_base($form, $langcode);
|
126 |
|
|
if ($groups) {
|
127 |
|
|
// I we've got groups, string list is grouped by group key.
|
128 |
|
|
$form['string_groups'] = array('#type' => 'value', '#value' => $strings);
|
129 |
|
|
foreach ($groups as $key => $title) {
|
130 |
|
|
$form['display'] = array(
|
131 |
|
|
'#type' => 'vertical_tabs',
|
132 |
|
|
);
|
133 |
|
|
$form['strings'][$key] = array(
|
134 |
|
|
'#group' => 'display',
|
135 |
|
|
'#title' => $title,
|
136 |
|
|
'#type' => 'fieldset',
|
137 |
|
|
) + i18n_string_translate_page_form_strings($strings[$key], $langcode);
|
138 |
|
|
}
|
139 |
|
|
}
|
140 |
|
|
else {
|
141 |
|
|
// We add a single group with key 'all', but no tabs.
|
142 |
|
|
$form['string_groups'] = array('#type' => 'value', '#value' => array('all' => $strings));
|
143 |
|
|
$form['strings']['all'] = i18n_string_translate_page_form_strings($strings, $langcode);
|
144 |
|
|
}
|
145 |
|
|
return $form;
|
146 |
|
|
}
|
147 |
|
|
|
148 |
|
|
/**
|
149 |
|
|
* Create base form for string translation
|
150 |
|
|
*/
|
151 |
|
|
function i18n_string_translate_page_form_base($form, $langcode, $redirect = NULL) {
|
152 |
|
|
$form['langcode'] = array(
|
153 |
|
|
'#type' => 'value',
|
154 |
|
|
'#value' => $langcode,
|
155 |
|
|
);
|
156 |
|
|
$form['submit'] = array(
|
157 |
|
|
'#type' => 'submit',
|
158 |
|
|
'#value' => t('Save translation'),
|
159 |
|
|
'#weight' => 10,
|
160 |
|
|
);
|
161 |
|
|
if ($redirect) {
|
162 |
|
|
$form['#redirect'] = array(
|
163 |
|
|
$redirect,
|
164 |
|
|
);
|
165 |
|
|
}
|
166 |
|
|
// Add explicit validate and submit hooks so this can be used from inside any form.
|
167 |
|
|
$form['#submit'] = array('i18n_string_translate_page_form_submit');
|
168 |
|
|
return $form;
|
169 |
|
|
}
|
170 |
|
|
|
171 |
|
|
/**
|
172 |
|
|
* Create field elements for strings
|
173 |
8c72e82a
|
Assos Assos
|
*
|
174 |
|
|
* @param i18n_string_object[] $strings
|
175 |
|
|
* @param string $langcode
|
176 |
|
|
*
|
177 |
|
|
* @return array
|
178 |
85ad3d82
|
Assos Assos
|
*/
|
179 |
|
|
function i18n_string_translate_page_form_strings($strings, $langcode) {
|
180 |
8c72e82a
|
Assos Assos
|
global $user;
|
181 |
|
|
$form = array();
|
182 |
85ad3d82
|
Assos Assos
|
foreach ($strings as $item) {
|
183 |
|
|
// Check permissions to translate this string, depends on format, etc..
|
184 |
|
|
if ($message = $item->check_translate_access()) {
|
185 |
|
|
// We'll display a disabled element with the reason it cannot be translated.
|
186 |
|
|
$disabled = TRUE;
|
187 |
|
|
$description = $message;
|
188 |
|
|
}
|
189 |
|
|
else {
|
190 |
|
|
$disabled = FALSE;
|
191 |
|
|
$description = '';
|
192 |
|
|
// If we don't have a source and it can be translated, we create it.
|
193 |
8c72e82a
|
Assos Assos
|
if (!$item->get_source()) {
|
194 |
85ad3d82
|
Assos Assos
|
// Enable messages just as a reminder these strings are not being updated properly.
|
195 |
|
|
$status = $item->update(array('messages' => TRUE));
|
196 |
|
|
if ($status === FALSE || $status === SAVED_DELETED) {
|
197 |
|
|
// We don't have a source string so nothing to translate here
|
198 |
|
|
$disabled = TRUE;
|
199 |
|
|
}
|
200 |
|
|
}
|
201 |
|
|
}
|
202 |
|
|
|
203 |
|
|
$default_value = $item->format_translation($langcode, array('langcode' => $langcode, 'sanitize' => FALSE, 'debug' => FALSE));
|
204 |
8c72e82a
|
Assos Assos
|
$available_formats = array_keys(filter_formats($user));
|
205 |
|
|
if (!in_array($item->format, $available_formats)) {
|
206 |
|
|
$item->format = NULL;
|
207 |
|
|
}
|
208 |
85ad3d82
|
Assos Assos
|
$form[$item->get_name()] = array(
|
209 |
|
|
'#title' => $item->get_title(),
|
210 |
8c72e82a
|
Assos Assos
|
'#type' => $item->format ? 'text_format' : 'textarea',
|
211 |
85ad3d82
|
Assos Assos
|
'#default_value' => $default_value,
|
212 |
8c72e82a
|
Assos Assos
|
'#format' => $item->format,
|
213 |
|
|
// This will trigger i18n_string_pre_render_text_format() to actually
|
214 |
|
|
// alter the element.
|
215 |
|
|
'#i18n_string_is_translation' => TRUE,
|
216 |
85ad3d82
|
Assos Assos
|
'#disabled' => $disabled,
|
217 |
8c72e82a
|
Assos Assos
|
'#description' => $description,
|
218 |
85ad3d82
|
Assos Assos
|
// If disabled, provide smaller textarea (that can be expanded anyway).
|
219 |
|
|
'#rows' => $disabled ? 1 : min(ceil(str_word_count($default_value) / 12), 10),
|
220 |
|
|
// Change the parent for disabled strings so we don't get empty values later
|
221 |
|
|
'#parents' => array($disabled ? 'disabled_strings': 'strings', $item->get_name()),
|
222 |
|
|
);
|
223 |
|
|
}
|
224 |
|
|
return $form;
|
225 |
|
|
}
|
226 |
|
|
|
227 |
|
|
/**
|
228 |
|
|
* Form submission callback for in-place string translation.
|
229 |
|
|
*/
|
230 |
|
|
function i18n_string_translate_page_form_submit($form, &$form_state) {
|
231 |
|
|
$count = $success = 0;
|
232 |
|
|
foreach ($form_state['values']['strings'] as $name => $value) {
|
233 |
|
|
$count++;
|
234 |
|
|
list($textgroup, $context) = i18n_string_context(explode(':', $name));
|
235 |
8c72e82a
|
Assos Assos
|
if (is_array($value)) {
|
236 |
|
|
if (isset($value['value'])) {
|
237 |
|
|
$value = $value['value'];
|
238 |
|
|
$form_state['values']['strings'][$name] = $value;
|
239 |
|
|
}
|
240 |
|
|
else {
|
241 |
|
|
form_set_error("strings][$name", t('Unable to get the translated string value.'));
|
242 |
|
|
watchdog('locale', 'Unable to get the translated string value, string array is: %string', array('%string' => var_dump($value)), WATCHDOG_WARNING);
|
243 |
|
|
}
|
244 |
|
|
}
|
245 |
85ad3d82
|
Assos Assos
|
$result = i18n_string_textgroup($textgroup)->update_translation($context, $form_state['values']['langcode'], $value);
|
246 |
|
|
$success += ($result ? 1 : 0);
|
247 |
|
|
}
|
248 |
|
|
if ($success) {
|
249 |
|
|
drupal_set_message(format_plural($success, 'A translation was saved successfully.', '@count translations were saved successfully.'));
|
250 |
|
|
}
|
251 |
|
|
if ($error = $count - $success) {
|
252 |
|
|
drupal_set_message(format_plural($error, 'A translation could not be saved.', '@count translations could not be saved.'), 'warning');
|
253 |
|
|
}
|
254 |
|
|
if (isset($form['#redirect'])) {
|
255 |
|
|
$form_state['redirect'] = $form['#redirect'];
|
256 |
|
|
}
|
257 |
|
|
}
|
258 |
|
|
|
259 |
|
|
/**
|
260 |
|
|
* Menu callback. Saves a string translation coming as POST data.
|
261 |
|
|
*/
|
262 |
|
|
function i18n_string_l10n_client_save_string() {
|
263 |
|
|
global $user, $language;
|
264 |
|
|
|
265 |
|
|
if (user_access('use on-page translation')) {
|
266 |
|
|
$textgroup = !empty($_POST['textgroup']) ? $_POST['textgroup'] : 'default';
|
267 |
|
|
// Other textgroups will be handled by l10n_client module
|
268 |
|
|
if (!i18n_string_group_info($textgroup)) {
|
269 |
|
|
return l10n_client_save_string();
|
270 |
|
|
}
|
271 |
|
|
elseif (isset($_POST['source']) && isset($_POST['target']) && !empty($_POST['context']) && !empty($_POST['form_token']) && drupal_valid_token($_POST['form_token'], 'l10n_client_form')) {
|
272 |
|
|
$name = $textgroup . ':' . $_POST['context'];
|
273 |
|
|
if ($i18nstring = i18n_string_get_source($name)) {
|
274 |
|
|
// Since this is not a real form, we double check access permissions here too.
|
275 |
|
|
if ($error = $i18nstring->check_translate_access()) {
|
276 |
|
|
$message = theme('l10n_client_message', array('message' => t('Not saved due to: !reason', array('!reason' => $error)), 'level' => WATCHDOG_WARNING));
|
277 |
|
|
}
|
278 |
|
|
else {
|
279 |
|
|
$result = i18n_string_translation_update($name, $_POST['target'], $language->language, $_POST['source']);
|
280 |
|
|
if ($result) {
|
281 |
|
|
$message = theme('l10n_client_message', array('message' => t('Translation saved locally for user defined string.'), 'level' => WATCHDOG_INFO));
|
282 |
|
|
}
|
283 |
|
|
elseif ($result === FALSE) {
|
284 |
|
|
$message = theme('l10n_client_message', array('message' => t('Not saved due to insufficient permissions.')));
|
285 |
|
|
}
|
286 |
|
|
else {
|
287 |
|
|
$message = theme('l10n_client_message', array('message' => t('Not saved due to unknown reason.')));
|
288 |
|
|
}
|
289 |
|
|
}
|
290 |
|
|
}
|
291 |
|
|
else {
|
292 |
|
|
$message = theme('l10n_client_message', array('message' => t('Not saved due to source string missing.')));
|
293 |
|
|
}
|
294 |
|
|
}
|
295 |
|
|
else {
|
296 |
|
|
$message = theme('l10n_client_message', array('message' => t('Not saved due to missing form values.')));
|
297 |
|
|
}
|
298 |
|
|
drupal_json_output($message);
|
299 |
|
|
exit;
|
300 |
|
|
}
|
301 |
|
|
}
|
302 |
|
|
|
303 |
|
|
|
304 |
|
|
/**
|
305 |
|
|
* User interface for string editing.
|
306 |
|
|
*/
|
307 |
|
|
function i18n_string_locale_translate_edit_form($form, &$form_state, $lid) {
|
308 |
|
|
// Fetch source string, if possible.
|
309 |
|
|
$source = db_query('SELECT source, context, textgroup, location FROM {locales_source} WHERE lid = :lid', array(':lid' => $lid))->fetchObject();
|
310 |
|
|
if (!$source) {
|
311 |
|
|
drupal_set_message(t('String not found.'), 'error');
|
312 |
|
|
drupal_goto('admin/config/regional/translate/translate');
|
313 |
|
|
}
|
314 |
|
|
|
315 |
|
|
// Add original text to the top and some values for form altering.
|
316 |
|
|
$form['original'] = array(
|
317 |
|
|
'#type' => 'item',
|
318 |
|
|
'#title' => t('Original text'),
|
319 |
|
|
'#markup' => check_plain(wordwrap($source->source, 0)),
|
320 |
|
|
);
|
321 |
|
|
if (!empty($source->context)) {
|
322 |
|
|
$form['context'] = array(
|
323 |
|
|
'#type' => 'item',
|
324 |
|
|
'#title' => t('Context'),
|
325 |
|
|
'#markup' => check_plain($source->context),
|
326 |
|
|
);
|
327 |
|
|
}
|
328 |
|
|
$form['lid'] = array(
|
329 |
|
|
'#type' => 'value',
|
330 |
|
|
'#value' => $lid
|
331 |
|
|
);
|
332 |
|
|
$form['textgroup'] = array(
|
333 |
|
|
'#type' => 'value',
|
334 |
|
|
'#value' => $source->textgroup,
|
335 |
|
|
);
|
336 |
|
|
$form['location'] = array(
|
337 |
|
|
'#type' => 'value',
|
338 |
|
|
'#value' => $source->location
|
339 |
|
|
);
|
340 |
|
|
|
341 |
|
|
// Include default form controls with empty values for all languages.
|
342 |
|
|
// This ensures that the languages are always in the same order in forms.
|
343 |
|
|
$languages = language_list();
|
344 |
|
|
|
345 |
|
|
// We don't need the default language value, that value is in $source.
|
346 |
|
|
$omit = $source->textgroup == 'default' ? 'en' : i18n_string_source_language();
|
347 |
|
|
unset($languages[($omit)]);
|
348 |
|
|
$form['translations'] = array('#tree' => TRUE);
|
349 |
|
|
// Approximate the number of rows to use in the default textarea.
|
350 |
|
|
$rows = min(ceil(str_word_count($source->source) / 12), 10);
|
351 |
|
|
foreach ($languages as $langcode => $language) {
|
352 |
|
|
$form['translations'][$langcode] = array(
|
353 |
|
|
'#type' => 'textarea',
|
354 |
|
|
'#title' => t($language->name),
|
355 |
|
|
'#rows' => $rows,
|
356 |
|
|
'#default_value' => '',
|
357 |
|
|
);
|
358 |
|
|
}
|
359 |
|
|
|
360 |
|
|
// Fetch translations and fill in default values in the form.
|
361 |
|
|
$result = db_query("SELECT DISTINCT translation, language FROM {locales_target} WHERE lid = :lid AND language <> :omit", array(':lid' => $lid, ':omit' => $omit));
|
362 |
|
|
foreach ($result as $translation) {
|
363 |
|
|
$form['translations'][$translation->language]['#default_value'] = $translation->translation;
|
364 |
|
|
}
|
365 |
|
|
|
366 |
|
|
$form['actions'] = array('#type' => 'actions');
|
367 |
|
|
$form['actions']['submit'] = array('#type' => 'submit', '#value' => t('Save translations'));
|
368 |
|
|
|
369 |
|
|
// Restrict filter permissions and handle validation and submission for i18n strings.
|
370 |
|
|
if (i18n_string_group_info($source->textgroup)) {
|
371 |
|
|
if ($i18nstring = i18n_string_get_by_lid($form['lid']['#value'])) {
|
372 |
|
|
$form['i18n_string'] = array('#type' => 'value', '#value' => $i18nstring);
|
373 |
|
|
if ($message = $i18nstring->check_translate_access()) {
|
374 |
|
|
drupal_set_message($message);
|
375 |
|
|
$disabled = TRUE;
|
376 |
|
|
}
|
377 |
|
|
// Add format help anyway, though the form may be disabled.
|
378 |
|
|
$form['translations']['format_help']['#markup'] = _i18n_string_translate_format_help($i18nstring->format);
|
379 |
|
|
}
|
380 |
|
|
else {
|
381 |
|
|
drupal_set_message(t('Source string not found.'), 'warning');
|
382 |
|
|
$disabled = TRUE;
|
383 |
|
|
}
|
384 |
|
|
if (!empty($disabled)) {
|
385 |
|
|
// Disable all form elements
|
386 |
|
|
$form['submit']['#disabled'] = TRUE;
|
387 |
|
|
foreach (element_children($form['translations']) as $langcode) {
|
388 |
|
|
$form['translations'][$langcode]['#disabled'] = TRUE;
|
389 |
|
|
}
|
390 |
|
|
}
|
391 |
|
|
}
|
392 |
|
|
return $form;
|
393 |
|
|
}
|
394 |
|
|
|
395 |
|
|
/**
|
396 |
|
|
* Process string editing form validations.
|
397 |
|
|
*
|
398 |
|
|
* If it is an allowed format, skip default validation, the text will be filtered later
|
399 |
|
|
*/
|
400 |
|
|
function i18n_string_locale_translate_edit_form_validate($form, &$form_state) {
|
401 |
|
|
if (empty($form_state['values']['i18n_string'])) {
|
402 |
|
|
// If not i18n string use regular locale validation.
|
403 |
|
|
$copy_state = $form_state;
|
404 |
|
|
locale_translate_edit_form_validate($form, $copy_state);
|
405 |
|
|
}
|
406 |
|
|
}
|
407 |
|
|
|
408 |
|
|
/**
|
409 |
|
|
* Process string editing form submissions.
|
410 |
|
|
*
|
411 |
|
|
* Mark translations as current.
|
412 |
|
|
*/
|
413 |
|
|
function i18n_string_locale_translate_edit_form_submit($form, &$form_state) {
|
414 |
|
|
// Invoke locale submission.
|
415 |
|
|
locale_translate_edit_form_submit($form, $form_state);
|
416 |
|
|
$lid = $form_state['values']['lid'];
|
417 |
e4c061ad
|
Assos Assos
|
if ($i18n_string_object = i18n_string_get_by_lid($lid)) {
|
418 |
|
|
$i18n_string_object->cache_reset();
|
419 |
|
|
}
|
420 |
85ad3d82
|
Assos Assos
|
foreach ($form_state['values']['translations'] as $key => $value) {
|
421 |
|
|
if (!empty($value)) {
|
422 |
|
|
// An update has been made, so we assume the translation is now current.
|
423 |
|
|
db_update('locales_target')
|
424 |
|
|
->fields(array('i18n_status' => I18N_STRING_STATUS_CURRENT))
|
425 |
|
|
->condition('lid', $lid)
|
426 |
|
|
->condition('language', $key)
|
427 |
|
|
->execute();
|
428 |
|
|
}
|
429 |
|
|
}
|
430 |
|
|
}
|
431 |
|
|
|
432 |
|
|
/**
|
433 |
|
|
* Help for text format.
|
434 |
|
|
*/
|
435 |
|
|
function _i18n_string_translate_format_help($format_id) {
|
436 |
|
|
$output = '';
|
437 |
|
|
if ($format = filter_format_load($format_id)) {
|
438 |
|
|
$title = t('Text format: @name', array('@name' => $format->name));
|
439 |
|
|
$tips = theme('filter_tips', array('tips' => _filter_tips($format_id, FALSE)));
|
440 |
|
|
}
|
441 |
|
|
elseif ($format_id == I18N_STRING_FILTER_XSS) {
|
442 |
|
|
$title = t('Standard XSS filter.');
|
443 |
|
|
$allowed_html = '<a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd>';
|
444 |
|
|
$tips[] = t('Allowed HTML tags: @tags', array('@tags' => $allowed_html));
|
445 |
|
|
}
|
446 |
|
|
elseif ($format_id == I18N_STRING_FILTER_XSS_ADMIN) {
|
447 |
|
|
$title = t('Administration XSS filter.');
|
448 |
|
|
$tips[] = t('It will allow most HTML tags but not scripts nor styles.');
|
449 |
|
|
}
|
450 |
|
|
elseif ($format_id) {
|
451 |
|
|
$title = t('Unknown filter: @name', array('@name' => $format_id));
|
452 |
|
|
}
|
453 |
|
|
|
454 |
|
|
if (!empty($title)) {
|
455 |
|
|
$output .= '<h5>' . $title . '</h5>';
|
456 |
|
|
}
|
457 |
|
|
if (!empty($tips)) {
|
458 |
|
|
$output .= is_array($tips) ? theme('item_list', array('items' => $tips)) : $tips;
|
459 |
|
|
}
|
460 |
|
|
return $output;
|
461 |
|
|
}
|
462 |
9faa5de0
|
Assos Assos
|
|
463 |
|
|
/**
|
464 |
|
|
* String search & translate screen.
|
465 |
|
|
*
|
466 |
|
|
* Almost exactly the same as the core locale module's implementation, but
|
467 |
|
|
* taking i18n_string_source_language into account for the languages column.
|
468 |
|
|
*/
|
469 |
|
|
function i18n_string_locale_translate_seek_screen() {
|
470 |
|
|
// Add CSS.
|
471 |
|
|
drupal_add_css(drupal_get_path('module', 'locale') . '/locale.css');
|
472 |
|
|
|
473 |
|
|
$elements = drupal_get_form('locale_translation_filter_form');
|
474 |
|
|
$output = drupal_render($elements);
|
475 |
|
|
$output .= _i18n_string_locale_translate_seek();
|
476 |
|
|
return $output;
|
477 |
|
|
}
|
478 |
|
|
|
479 |
|
|
/**
|
480 |
|
|
* Perform a string search and display results in a table
|
481 |
|
|
*/
|
482 |
|
|
function _i18n_string_locale_translate_seek() {
|
483 |
|
|
$output = '';
|
484 |
|
|
|
485 |
|
|
// We have at least one criterion to match
|
486 |
|
|
if (!($query = _locale_translate_seek_query())) {
|
487 |
|
|
$query = array(
|
488 |
|
|
'translation' => 'all',
|
489 |
|
|
'group' => 'all',
|
490 |
|
|
'language' => 'all',
|
491 |
|
|
'string' => '',
|
492 |
|
|
);
|
493 |
|
|
}
|
494 |
|
|
|
495 |
|
|
$sql_query = db_select('locales_source', 's');
|
496 |
|
|
|
497 |
|
|
$limit_language = NULL;
|
498 |
|
|
if ($query['language'] != 'en' && $query['language'] != 'all') {
|
499 |
|
|
$sql_query->leftJoin('locales_target', 't', "t.lid = s.lid AND t.language = :langcode", array(':langcode' => $query['language']));
|
500 |
|
|
$limit_language = $query['language'];
|
501 |
|
|
}
|
502 |
|
|
else {
|
503 |
|
|
$sql_query->leftJoin('locales_target', 't', 't.lid = s.lid');
|
504 |
|
|
}
|
505 |
|
|
|
506 |
|
|
$sql_query->fields('s', array('source', 'location', 'context', 'lid', 'textgroup'));
|
507 |
|
|
$sql_query->fields('t', array('translation', 'language'));
|
508 |
|
|
|
509 |
|
|
// Compute LIKE section.
|
510 |
|
|
switch ($query['translation']) {
|
511 |
|
|
case 'translated':
|
512 |
|
|
$sql_query->condition('t.translation', '%' . db_like($query['string']) . '%', 'LIKE');
|
513 |
|
|
$sql_query->orderBy('t.translation', 'DESC');
|
514 |
|
|
break;
|
515 |
|
|
case 'untranslated':
|
516 |
|
|
$sql_query->condition(db_and()
|
517 |
|
|
->condition('s.source', '%' . db_like($query['string']) . '%', 'LIKE')
|
518 |
|
|
->isNull('t.translation')
|
519 |
|
|
);
|
520 |
|
|
$sql_query->orderBy('s.source');
|
521 |
|
|
break;
|
522 |
|
|
case 'all' :
|
523 |
|
|
default:
|
524 |
|
|
$condition = db_or()
|
525 |
|
|
->condition('s.source', '%' . db_like($query['string']) . '%', 'LIKE');
|
526 |
|
|
if ($query['language'] != 'en') {
|
527 |
|
|
// Only search in translations if the language is not forced to English.
|
528 |
|
|
$condition->condition('t.translation', '%' . db_like($query['string']) . '%', 'LIKE');
|
529 |
|
|
}
|
530 |
|
|
$sql_query->condition($condition);
|
531 |
|
|
break;
|
532 |
|
|
}
|
533 |
|
|
|
534 |
|
|
// Add a condition on the text group.
|
535 |
|
|
if (!empty($query['group']) && $query['group'] != 'all') {
|
536 |
|
|
$sql_query->condition('s.textgroup', $query['group']);
|
537 |
|
|
}
|
538 |
|
|
|
539 |
|
|
$sql_query = $sql_query->extend('PagerDefault')->limit(50);
|
540 |
|
|
$locales = $sql_query->execute();
|
541 |
|
|
|
542 |
|
|
$groups = module_invoke_all('locale', 'groups');
|
543 |
|
|
$header = array(t('Text group'), t('String'), t('Context'), ($limit_language) ? t('Language') : t('Languages'), array('data' => t('Operations'), 'colspan' => '2'));
|
544 |
|
|
|
545 |
|
|
$strings = array();
|
546 |
|
|
foreach ($locales as $locale) {
|
547 |
|
|
if (!isset($strings[$locale->lid])) {
|
548 |
|
|
$strings[$locale->lid] = array(
|
549 |
|
|
'group' => $locale->textgroup,
|
550 |
|
|
'languages' => array(),
|
551 |
|
|
'location' => $locale->location,
|
552 |
|
|
'source' => $locale->source,
|
553 |
|
|
'context' => $locale->context,
|
554 |
|
|
);
|
555 |
|
|
}
|
556 |
|
|
if (isset($locale->language)) {
|
557 |
|
|
$strings[$locale->lid]['languages'][$locale->language] = $locale->translation;
|
558 |
|
|
}
|
559 |
|
|
}
|
560 |
|
|
|
561 |
|
|
$rows = array();
|
562 |
|
|
foreach ($strings as $lid => $string) {
|
563 |
|
|
$rows[] = array(
|
564 |
|
|
$groups[$string['group']],
|
565 |
|
|
array('data' => check_plain(truncate_utf8($string['source'], 150, FALSE, TRUE)) . '<br /><small>' . $string['location'] . '</small>'),
|
566 |
|
|
$string['context'],
|
567 |
|
|
array('data' => _i18n_string_locale_translate_language_list($string, $limit_language), 'align' => 'center'),
|
568 |
|
|
array('data' => l(t('edit'), "admin/config/regional/translate/edit/$lid", array('query' => drupal_get_destination())), 'class' => array('nowrap')),
|
569 |
|
|
array('data' => l(t('delete'), "admin/config/regional/translate/delete/$lid", array('query' => drupal_get_destination())), 'class' => array('nowrap')),
|
570 |
|
|
);
|
571 |
|
|
}
|
572 |
|
|
|
573 |
|
|
$output .= theme('table', array('header' => $header, 'rows' => $rows, 'empty' => t('No strings available.')));
|
574 |
|
|
$output .= theme('pager');
|
575 |
|
|
|
576 |
|
|
return $output;
|
577 |
|
|
}
|
578 |
|
|
|
579 |
|
|
/**
|
580 |
|
|
* List languages in search result table.
|
581 |
|
|
*/
|
582 |
|
|
function _i18n_string_locale_translate_language_list($string, $limit_language) {
|
583 |
|
|
// Add CSS.
|
584 |
|
|
drupal_add_css(drupal_get_path('module', 'locale') . '/locale.css');
|
585 |
|
|
|
586 |
|
|
// Include both translated and not yet translated target languages in the
|
587 |
|
|
// list. The source language is English for built-in strings and the default
|
588 |
|
|
// language for other strings.
|
589 |
|
|
$languages = language_list();
|
590 |
|
|
$default = language_default();
|
591 |
|
|
$omit = $string['group'] == 'default' ? 'en' : variable_get('i18n_string_source_language', $default->language);
|
592 |
|
|
unset($languages[$omit]);
|
593 |
|
|
$output = '';
|
594 |
|
|
foreach ($languages as $langcode => $language) {
|
595 |
|
|
if (!$limit_language || $limit_language == $langcode) {
|
596 |
|
|
$output .= (!empty($string['languages'][$langcode])) ? $langcode . ' ' : "<em class=\"locale-untranslated\">$langcode</em> ";
|
597 |
|
|
}
|
598 |
|
|
}
|
599 |
|
|
|
600 |
|
|
return $output;
|
601 |
|
|
} |