/[drupal]/contributions/modules/i18n_auto/i18n_auto.module
ViewVC logotype

Contents of /contributions/modules/i18n_auto/i18n_auto.module

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


Revision 1.4 - (show annotations) (download) (as text)
Wed Jan 9 19:56:37 2008 UTC (22 months, 2 weeks ago) by aaron
Branch: MAIN
CVS Tags: HEAD
Changes since 1.3: +16 -2 lines
File MIME type: text/x-php
#159323/dman - begin support for multiple languages
1 <?php
2 // $Id: i18n_auto.module,v 1.2 2007/06/06 20:17:56 aaron Exp $
3
4 /**
5 * Implement hook_menu
6 */
7 function i18n_auto_menu($may_cache) {
8 $items = array();
9 if ($may_cache) {
10 $items[] = array(
11 'path' => 'admin/settings/i18n/auto',
12 'title' => t('Auto Translation'),
13 'type' => MENU_LOCAL_TASK,
14 'callback' => 'drupal_get_form',
15 'callback arguments' => array('i18n_auto_admin_settings'),
16 'weight' => 3,
17 'access' => user_access('administer i18n auto'),
18 );
19 $items[] = array(
20 'path' => 'i18n_auto/translate',
21 'callback' => '_i18n_auto_translate',
22 'type' => MENU_CALLBACK,
23 'access' => user_access('i18n auto translate'),
24 );
25 }
26 return $items;
27 }
28
29 /**
30 * Implement hook_perm
31 */
32 function i18n_auto_perm() {
33 return array('i18n auto translate', 'administer i18n auto');
34 }
35
36 /**
37 * This displays the global settings for auto translate. It will create a field for each 3rd party translator included
38 * in the /translators directory of the i18n_auto module directory. When writing your own include file, you may include
39 * a fieldset for your translator by implementing the i18n_auto_TRANSLATOR_settings hook (replacing TRANSLATOR with the
40 * name of your .inc file).
41 */
42 function i18n_auto_admin_settings() {
43 $form = array();
44 $translators = i18n_auto_system_list();
45 foreach ($translators as $translator) {
46 $info = i18n_auto_include_invoke($translator->name, 'info');
47 $form[$translator->name] = array(
48 '#type' => 'fieldset',
49 '#title' => t('@translator Configuration', array('@translator' => $info['name'])),
50 '#description' => $info['settings_description'],
51 '#collapsible' => true,
52 '#collapsed' => true,
53 );
54 $form[$translator->name][] = i18n_auto_include_invoke($translator->name, 'settings');
55 $form[$translator->name]['i18n_auto_allow_' . $translator->name] = array(
56 '#type' => 'checkbox',
57 '#title' => t('Allow translation from %translator', array('%translator' => $info['name'])),
58 '#description' => t('If checked, then automatic translation may be provided by %translator.', array('%translator' => $info['name'])),
59 '#weight' => -10,
60 '#default_value' => variable_get('i18n_auto_allow_' . $translator->name, true),
61 );
62 }
63 return system_settings_form($form);
64 }
65
66 /**
67 * TODO: have it intelligently check which forms & textareas it's allowed to add a button to, and use jsquery
68 */
69 function i18n_auto_form_alter($form_id, &$form) {
70 // print "form: $form_id<br />\n";
71 // print_r($form);
72
73 if ($form['#id'] == 'node-form') {
74 $js = '';
75 foreach (_i18n_auto_form_iterate_for_textareas($form) as $element => $item) {
76 $field = 'i18n_auto_translate_' . $element;
77 $form[$field] = array(
78 '#type' => 'fieldset',
79 '#title' => t('Auto Translation'),
80 '#collapsible' => true,
81 '#collapsed' => false,
82 '#weight' => $item['#weight'],
83 '#attributes' => array(
84 '#class' => 'i18n-auto-fieldset',
85 ),
86 '#description' => t('Selecting one of these translation services will replace the text in the %textarea textarea with a translated version.', array('%textarea' => $item['#title'])),
87 );
88
89 $edit_id = form_clean_id('edit-' . $element);
90 $revert_id = form_clean_id('edit-' . 'i18n_auto_revert_' . $element);
91
92 $js .= "
93
94
95 i18n_original_text['$element'] = $('#$edit_id').attr('value');
96
97 $('#$revert_id').click(
98 function() {
99 $('#$edit_id').attr('value', i18n_original_text['$element']);
100 return false;
101 }
102 );
103 ";
104
105 $translators = i18n_auto_system_list();
106 foreach ($translators as $translator) {
107 $button = $field . '_' . $translator->name;
108 $form[$field][$button] = array(
109 '#type' => 'button',
110 '#value' => t('Translate with @translator', array('@translator' => $translator->name)),
111 );
112 $id = form_clean_id('edit-' . $button);
113
114 $link = url('i18n_auto/translate/' . $translator->name);
115 $js .= "
116 $('#$id').click(
117 function() {
118 return i18n_auto_click('#$id', '#$edit_id', '$element', '$link');
119 }
120 );
121 ";
122 }
123 $form[$field]['i18n_auto_revert_' . $element] = array(
124 '#type' => 'button',
125 '#value' => t('Revert to original', array('@translator' => $translator->name)),
126 );
127 }
128 if ($js) {
129 $js = "
130 if (Drupal.jsEnabled) {
131 function i18n_auto_click(_id, _edit_id, _element, _link) {
132 var _new_value = function(data) {
133 var result = Drupal.parseJson(data);
134 if (result['text']) {
135 i18n_original_text[_element] = $(_edit_id).attr('value');
136 $(_edit_id).attr('value', result['text']);
137 }
138 }
139 if ($(_edit_id).attr('value')) {
140 $.post(_link, {text: $(_edit_id).attr('value'), from: $('#edit-language').attr('value') }, _new_value);
141 }
142 return false;
143 }
144
145 var i18n_original_text = new Array();
146
147 $(document).ready(function(){\n" . $js . "\n });\n }\n\n";
148 drupal_add_js($js, 'inline');
149 }
150 }
151 }
152
153 function _i18n_auto_translate($translator) {
154 $translators = i18n_auto_system_list($translator);
155 if (!$translators[$translator]) {
156 drupal_not_found();
157 }
158 $text = $_POST['text'];
159 $from = $_POST['from'];
160 // TODO: change default language to drupal's locale's default language...
161 $to = $_POST['to'] ? $_POST['to'] : variable_get('i18n_auto_translate_to_lang_default', 'es');
162 // $translation = check_plain(i18n_auto_include_invoke($translator, 'translate', drupal_urlencode($text)));
163 $translation = i18n_auto_include_invoke($translator, 'translate', $text, $from, $to);
164 // Google flattens the input markup. Put it back
165 $translation = htmlspecialchars_decode($translation);
166 // print drupal_urlencode($translation);
167 print drupal_to_js(array('text' => $translation));
168 exit();
169 }
170
171 /**
172 * This will return all the (nested) textarea elements in a form.
173 */
174 function _i18n_auto_form_iterate_for_textareas($form) {
175 static $elements;
176
177 if (!isset($elements)) {
178 $elements = array();
179 }
180 foreach (element_children($form) as $element) {
181 $item = $form[$element];
182 if ($item['#type'] == 'textarea') {
183 $elements[$element] = $item;
184 }
185 else if (is_array($item)) {
186 _i18n_auto_form_iterate_for_textareas($item);
187 }
188 }
189 return $elements;
190 }
191
192 /**
193 * Return an array of installed .inc files and/or loads them upon request.
194 * This routine is modeled after drupal_system_listing() (and also depends on it).
195 * It's major difference, however, is that it loads .inc files by default.
196 *
197 * @param $translator
198 * Optional; name of the passed $translator to find (e.g. "youtube", "google", etc.).
199 * @param $load
200 * Defaults to true; whether to include matching files into memory.
201 * @return
202 * An array of file objects optionally matching $translator.
203 */
204 function i18n_auto_system_list($translator = NULL, $load = true) {
205 $files = drupal_system_listing("$translator\.inc", drupal_get_path('module', 'i18n_auto')."/translators", 'name', 0);
206
207 ksort($files);
208
209 if ($load) {
210 foreach ($files as $file) {
211 i18n_auto_include_list($file);
212 }
213 }
214
215 return $files;
216 }
217
218 /**
219 * Maintains a list of all loaded include files.
220 *
221 * @param $file
222 * Optional; a file object (from i18n_auto_system_list()) to be included.
223 * @return
224 * An array of all loaded includes (without the .inc extension).
225 */
226 function i18n_auto_include_list($file = NULL) {
227 static $list = array();
228
229 // if (!$list) { $list = array(); }
230
231 if ($file && !isset($list[$file->name])) {
232 include_once('./'.$file->filename);
233 $list[$file->name] = $file->name;
234 }
235
236 return $list;
237 }
238
239 /**
240 * Determine whether an include implements a hook, cf. module_hook.
241 *
242 * @param $translator
243 * The name of the translator file (without the .inc extension), such as 'youtube' or 'google'.
244 * @param $hook
245 * The name of the hook (e.g. "thumbnail", "settings", etc.).
246 * @return
247 * TRUE if the translator is loaded and the hook is implemented.
248 */
249 function i18n_auto_include_hook($translator, $hook) {
250 return function_exists('i18n_auto_' . $translator .'_'. $hook);
251 }
252
253 /**
254 * Invoke hook in a particular include.
255 *
256 * @param $translator
257 * The name of the translator (without the .inc extension).
258 * @param $hook
259 * The name of the hook (e.g. "settings", "thumbnail", etc.).
260 * @param ...
261 * Arguments to pass to the hook implementation.
262 * @return
263 * The return value of the hook implementation.
264 */
265 function i18n_auto_include_invoke() {
266 $args = func_get_args();
267 $translator = array_shift($args);
268 $hook = array_shift($args);
269 $function = 'i18n_auto_' . $translator . '_' . $hook;
270 i18n_auto_system_list($translator);
271 return i18n_auto_include_hook($translator, $hook) ? call_user_func_array($function, $args) : NULL;
272 }
273
274 // to support PHP 4 users...
275 if (!function_exists("htmlspecialchars_decode")) {
276 function htmlspecialchars_decode($string, $quote_style = ENT_COMPAT) {
277 return strtr($string, array_flip(get_html_translation_table(HTML_SPECIALCHARS, $quote_style)));
278 }
279 }
280

  ViewVC Help
Powered by ViewVC 1.1.2