/[drupal]/contributions/modules/translation_overview/translation_overview.pages.inc
ViewVC logotype

Contents of /contributions/modules/translation_overview/translation_overview.pages.inc

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


Revision 1.9 - (show annotations) (download) (as text)
Thu Apr 16 19:47:28 2009 UTC (7 months, 1 week ago) by drewish
Branch: MAIN
CVS Tags: DRUPAL-6--2-3, DRUPAL-6--2-2, DRUPAL-6--2-1, DRUPAL-6--2-1-BETA1, DRUPAL-6--2-1-BETA2, HEAD
Changes since 1.8: +3 -3 lines
File MIME type: text/x-php
#369800 by drewish: Rename the language columns in {translation_overview_priority} so they don't conflict with SQL reserved words.
1 <?php
2 // $Id: translation_overview.pages.inc,v 1.8 2008/10/23 01:51:12 drewish Exp $
3
4 function translation_overview_node_page($node) {
5 drupal_set_title(t('Translations of %title', array('%title' => $node->title)));
6
7 return drupal_get_form('translation_overview_node_form', $node);
8 }
9
10 /**
11 * Overview page for a node's translations.
12 *
13 * Based on the translation.module's translation_node_overview().
14 *
15 * @param $node
16 * Node object.
17 */
18 function translation_overview_node_form(&$form_state, $node) {
19 if ($node->tnid) {
20 // Already part of a set, grab that set.
21 $tnid = $node->tnid;
22 $translations = translation_node_get_translations($node->tnid);
23 }
24 else {
25 // We have no translation source nid, this could be a new set, emulate that.
26 $tnid = $node->nid;
27 $translations = array($node->language => $node);
28 }
29 $priorities = translation_overview_get_node_priority($node);
30
31 $form['languages']['#tree'] = TRUE;
32
33 foreach (language_list() as $lang_code => $language) {
34 // Skip over any disabled languages.
35 if (!$language->enabled) {
36 continue;
37 }
38
39 $form['languages'][$lang_code]['priority'] = array(
40 '#type' => 'radios',
41 '#default_value' => $priorities[$lang_code],
42 '#options' => array(
43 TRANSLATION_OVERVIEW_HIGH => t('High'),
44 TRANSLATION_OVERVIEW_NORMAL => t('Normal'),
45 TRANSLATION_OVERVIEW_IGNORE => t('Ignore'),
46 ),
47 // If there's no manager role then everyone gets a chance. Otherwise
48 // check that they're a manager for this language.
49 '#access' => translation_overview_is_manager($lang_code),
50 );
51
52 if (isset($translations[$lang_code])) {
53 // Existing translation in the translation set: display status.
54 // We load the full node to check whether the user can edit it.
55 $translation_node = node_load($translations[$lang_code]->nid);
56 if ($translation_node->nid == $tnid) {
57 // Original shouldn't have a priority.
58 $form['languages'][$lang_code]['priority']['#access'] = FALSE;
59 $form['languages'][$lang_code]['language'] = array(
60 '#value' => '<strong>'. $language->name .'</strong> (source)',
61 );
62 }
63 else {
64 $form['languages'][$lang_code]['language'] = array(
65 '#value' => $language->name,
66 );
67 }
68 $form['languages'][$lang_code]['title'] = array(
69 '#value' => l($translation_node->title, 'node/'. $translation_node->nid),
70 );
71 $form['languages'][$lang_code]['status'] = array(
72 '#value' => translation_overview_translation_link($node, $translation_node, $lang_code, TRUE),
73 );
74 }
75 else {
76 // No such translation in the set yet: help user to create it.
77 $form['languages'][$lang_code]['language'] = array(
78 '#value' => $language->name,
79 );
80 $form['languages'][$lang_code]['title'] = array(
81 '#value' => t('n/a'),
82 );
83 $form['languages'][$lang_code]['status'] = array(
84 '#value' => translation_overview_translation_link($node, NULL, $lang_code, TRUE),
85 );
86 }
87 }
88
89 $form['tnid'] = array(
90 '#type' => 'value',
91 '#value' => $tnid,
92 );
93 $form['submit'] = array(
94 '#type' => 'submit',
95 '#value' => t('Submit'),
96 );
97
98 return $form;
99 }
100
101 function translation_overview_node_form_submit($form, &$form_state) {
102 $row = array('tnid' => (int) $form_state['values']['tnid']);
103 foreach ($form_state['values']['languages'] as $language => $values) {
104 $row[translation_overview_field_name($language)] = $values['priority'];
105 }
106
107 // We can assume that there will alwyas be a record with the given tnid
108 // because translation_overview_get_node_priority() has been called and it
109 // creates records if one is not present.
110 if (drupal_write_record('translation_overview_priority', $row, 'tnid') !== FALSE) {
111 drupal_set_message(t('The translation priorities have been saved.'));
112 }
113 else {
114 drupal_set_message(t('There was a problem saving the translation priorities.'), 'error');
115 }
116 }
117
118
119 function theme_translation_overview_node_form($form) {
120 drupal_add_css(drupal_get_path('module', 'translation_overview') .'/translation_overview.css');
121
122 $is_manager = translation_overview_is_manager();
123
124 $header = array(
125 array('data' => t('Language')),
126 array('data' => t('Title')),
127 array('data' => t('Status')),
128 );
129
130 if ($is_manager) {
131 $header[] = array('data' => t('Priority'), 'colspan' => 3);
132 }
133
134 $rows = array();
135 foreach (element_children($form['languages']) as $key) {
136 $row = array();
137 $row[] = array('data' => drupal_render($form['languages'][$key]['language']));
138 $row[] = array('data' => drupal_render($form['languages'][$key]['title']));
139 $row[] = array('data' => drupal_render($form['languages'][$key]['status']), 'class' => 'status');
140 if ($is_manager) {
141 foreach (element_children($form['languages'][$key]['priority']) as $priority) {
142 $row[] = array('data' => drupal_render($form['languages'][$key]['priority'][$priority]));
143 }
144 }
145 $rows[] = $row;
146 }
147 return theme('table', $header, $rows, array('class' => 'trov')) . drupal_render($form);
148 }
149
150
151 /**
152 * List node administration filters that can be applied.
153 *
154 * This is a fork of node_filters().
155 */
156 function translation_overview_node_filters() {
157 // Regular filters
158 $filters['status'] = array(
159 'title' => t('Status'),
160 'options' => array(
161 'status-1' => t('Published'),
162 'status-0' => t('Not published'),
163 'promote-1' => t('Promoted'),
164 'promote-0' => t('Not promoted'),
165 'sticky-1' => t('Sticky'),
166 'sticky-0' => t('Not sticky'),
167 'translate-0' => t('Up-to-date translation'),
168 'translate-1' => t('Outdated translation'),
169 ),
170 );
171
172 $filters['type'] = array(
173 'title' => t('type'),
174 'options' => translation_overview_node_types(),
175 );
176
177 // The taxonomy filter
178 if ($taxonomy = module_invoke('taxonomy', 'form_all', 1)) {
179 $filters['category'] = array('title' => t('category'), 'options' => $taxonomy);
180 }
181
182 return $filters;
183 }
184
185 /**
186 * Return form for node administration filters.
187 *
188 * This is a fork of node_filter_form().
189 */
190 function translation_overview_filter_form() {
191 // We reuse a bunch of the node.module's stuff.
192 module_load_include('inc', 'node', 'node.admin');
193
194 $session = &$_SESSION['translation_overview_filter'];
195 $session = is_array($session) ? $session : array();
196 $filters = translation_overview_node_filters();
197
198 $i = 0;
199 $form['filters'] = array(
200 '#type' => 'fieldset',
201 '#title' => t('Show only items where'),
202 '#theme' => 'node_filters',
203 );
204 $form['#submit'][] = 'translation_overview_filter_form_submit';
205 foreach ($session as $filter) {
206 list($type, $value) = $filter;
207 if ($type == 'category') {
208 // Load term name from DB rather than search and parse options array.
209 $value = module_invoke('taxonomy', 'get_term', $value);
210 $value = $value->name;
211 }
212 else {
213 $value = $filters[$type]['options'][$value];
214 }
215 if ($i++) {
216 $form['filters']['current'][] = array('#value' => t('<em>and</em> where <strong>%a</strong> is <strong>%b</strong>', array('%a' => $filters[$type]['title'], '%b' => $value)));
217 }
218 else {
219 $form['filters']['current'][] = array('#value' => t('<strong>%a</strong> is <strong>%b</strong>', array('%a' => $filters[$type]['title'], '%b' => $value)));
220 }
221 if (in_array($type, array('type', 'language'))) {
222 // Remove the option if it is already being filtered on.
223 unset($filters[$type]);
224 }
225 }
226
227 foreach ($filters as $key => $filter) {
228 $names[$key] = $filter['title'];
229 $form['filters']['status'][$key] = array('#type' => 'select', '#options' => $filter['options']);
230 }
231
232 $form['filters']['filter'] = array('#type' => 'radios', '#options' => $names, '#default_value' => 'status');
233 $form['filters']['buttons']['submit'] = array('#type' => 'submit', '#value' => (count($session) ? t('Refine') : t('Filter')));
234 if (count($session)) {
235 $form['filters']['buttons']['undo'] = array('#type' => 'submit', '#value' => t('Undo'));
236 $form['filters']['buttons']['reset'] = array('#type' => 'submit', '#value' => t('Reset'));
237 }
238
239 drupal_add_js('misc/form.js', 'core');
240
241 return $form;
242 }
243
244 /**
245 * Process result from node administration filter form.
246 *
247 * This is a fork of node_filter_form().
248 */
249 function translation_overview_filter_form_submit($form, &$form_state) {
250 $filters = translation_overview_node_filters();
251 switch ($form_state['values']['op']) {
252 case t('Filter'):
253 case t('Refine'):
254 if (isset($form_state['values']['filter'])) {
255 $filter = $form_state['values']['filter'];
256
257 // Flatten the options array to accommodate hierarchical/nested options.
258 $flat_options = form_options_flatten($filters[$filter]['options']);
259
260 if (isset($flat_options[$form_state['values'][$filter]])) {
261 $_SESSION['translation_overview_filter'][] = array($filter, $form_state['values'][$filter]);
262 }
263 }
264 break;
265 case t('Undo'):
266 array_pop($_SESSION['translation_overview_filter']);
267 break;
268 case t('Reset'):
269 $_SESSION['translation_overview_filter'] = array();
270 break;
271 }
272 }
273
274 /**
275 * Build the where clause for a filtered query.
276 *
277 * This is a fork of node_filter_form_submit().
278 */
279 function translation_overview_build_filter_query() {
280 $filters = translation_overview_node_filters();
281
282 // Build query
283 $join = $where = $where_args = array();
284 if (isset($_SESSION['translation_overview_filter'])) {
285 foreach ((array) $_SESSION['translation_overview_filter'] as $index => $filter) {
286 list($key, $value) = $filter;
287 switch ($key) {
288 case 'status':
289 // Note: no exploitable hole as $key/$value have already been checked when submitted
290 list($key, $value) = explode('-', $value, 2);
291 $where['status'] = 'n.'. $key .' = %d';
292 break;
293 case 'category':
294 $table = "tn$index";
295 $where[$table] = "$table.tid = %d";
296 $join[$table] = "INNER JOIN {term_node} $table ON n.nid = $table.nid ";
297 break;
298 case 'type':
299 $where['type'] = "n.type = '%s'";
300 break;
301 }
302 $where_args[] = $value;
303 }
304 }
305
306 // Make sure we limit it to translation enabled types.
307 if (empty($where['type'])) {
308 $types = array_keys(translation_overview_node_types());
309 $where[] = 'n.type IN ('. db_placeholders($types, 'varchar') .')';
310 $where_args = array_merge($where_args, $types);
311 }
312
313 return array('join' => $join, 'where' => $where, 'where_args' => $where_args);
314 }
315
316 /**
317 * Translation overview page.
318 */
319 function translation_overview_manager_page() {
320 drupal_add_css(drupal_get_path('module', 'translation_overview') .'/translation_overview.css');
321
322 $rows_per_page = 30;
323
324 // Get a list of the enabled languages that this user manages.
325 $languages = array();
326 foreach (language_list() as $key => $language) {
327 if ($language->enabled && translation_overview_is_manager($language->language)) {
328 $languages[$key] = $language->name;
329 }
330 }
331
332 // Bail if there are no translatable nodes
333 if (count(translation_overview_node_types()) == 0) {
334 drupal_set_message(t('There are no translatable node types on this site.'), 'error');
335 return '';
336 }
337
338 $header = array(
339 array('field' => 'n.title', 'data' => t('Title'), 'sort' => 'asc'),
340 array('field' => 'n.type', 'data' => t('Type')),
341 array('field' => 'n.created', 'data' => t('Created')),
342 );
343 foreach ($languages as $lang_code => $lang_name) {
344 $header[] = array('data' => str_replace('-', '-<br />', $lang_code), 'class' => 'trov-lang', 'title' => $lang_name);
345 }
346
347 $query = translation_overview_build_filter_query();
348 $sql = "SELECT n.nid, n.title, n.type, n.created FROM {node} n ". implode(' ', $query['join']) ."
349 WHERE (n.nid = n.tnid OR n.tnid = 0) AND n.language <> '' AND n.language IS NOT NULL
350 AND ". implode(' AND ', $query['where']) . tablesort_sql($header);
351
352 $rows = array();
353 $result = pager_query(db_rewrite_sql($sql), $rows_per_page, 0, NULL, $query['where_args']);
354 while ($node = db_fetch_object($result)) {
355 $node = node_load($node->nid);
356
357 $row = array(
358 array('data' => l(translation_overview_trimmed_title($node), 'node/'. $node->nid .'/translate', array('attributes' => array('title' => $node->title), 'query' => array('destination' => $_GET['q'])))),
359 array('data' => check_plain($node->type)),
360 array('data' => format_date($node->created, 'custom', 'j M Y')),
361 );
362
363 // Load the node's translations and then fill in the table with the status.
364 $translations = (array) translation_node_get_translations($node->tnid);
365 foreach ($languages as $lang_code => $lang_name) {
366 $translation = empty($translations[$lang_code]->nid) ? NULL : node_load($translations[$lang_code]->nid);
367 $row[$lang_code] = array(
368 'data' => translation_overview_translation_link($node, $translation, $lang_code, FALSE),
369 'class' => 'status',
370 );
371 }
372
373 $rows[] = $row;
374 }
375
376 return drupal_get_form('translation_overview_filter_form')
377 . theme('table', $header, $rows, array('class' => 'trov-all'))
378 . theme('pager', NULL, $rows_per_page);
379 }
380
381 /**
382 * Show a listing of the languages that translators can look at.
383 */
384 function translation_overview_assignment_lang_page() {
385 $items = array();
386 foreach (language_list() as $language) {
387 if ($language->enabled) {
388 $items[] = l($language->name, 'admin/content/translation_overview_assignments/'. $language->language);
389 }
390 }
391 return theme('item_list', $items);
392 }
393
394 function translation_overview_assignment_page($language) {
395 drupal_add_css(drupal_get_path('module', 'translation_overview') .'/translation_overview.css');
396
397 $rows_per_page = 30;
398 $node_types = node_get_types('names');
399 $languages = language_list();
400
401 // Bail if there are no translatable nodes
402 if (count(translation_overview_node_types()) == 0) {
403 drupal_set_message(t('There are no translatable node types on this site.'), 'error');
404 return '';
405 }
406
407 $header = array(
408 array('field' => 'n.title', 'data' => t('Title')),
409 array('field' => 'translation_status', 'data' => t('Status'), 'sort' => 'desc'),
410 array('field' => 'n.type', 'data' => t('Type')),
411 array('field' => 'n.language', 'data' => t('Source language')),
412 array('field' => 'n.created', 'data' => t('Created')),
413 );
414
415 // We want to sort the nodes by the status so we have to resort to this SQL
416 // CASE statement.
417 $rows = array();
418 $query = translation_overview_build_filter_query();
419 $language_field = translation_overview_field_name($language);
420 $sql = "SELECT n.nid, n.title, n.type, n.status, n.language, n.created, nt.nid AS translation_nid, CASE
421 WHEN n.language = '%s' " /* ORIGINAL */ ." THEN 0
422 WHEN nt.tnid IS NULL " /* MISSING */ ." THEN 3 + 2 * top.$language_field
423 WHEN nt.translate = 0 " /* COMPLETE */ ." THEN 1
424 WHEN n.nid = n.tnid " /* OUTDATED */ ." THEN 2 + 2 * top.$language_field
425 ELSE -1 END AS translation_status
426 FROM {node} n
427 LEFT JOIN {node} nt ON n.nid = nt.tnid AND nt.language = '%s'
428 INNER JOIN {translation_overview_priority} top ON n.nid = top.tnid AND top.$language_field <> %d
429 ". implode(' ', $query['join']) ."
430 WHERE (n.nid = n.tnid OR n.tnid = 0) AND n.language NOT IN ('', '%s') AND n.language IS NOT NULL
431 AND ". implode(' AND ', $query['where'])
432 . tablesort_sql($header);
433 // The %s in the CASE causes pager_query() to screw up the count query so build it by hand and eat the extra %s.
434 $count_sql = "SELECT COUNT(n.nid), '%s' AS junk
435 FROM {node} n
436 LEFT JOIN {node} nt ON n.nid = nt.tnid AND nt.language = '%s'
437 INNER JOIN {translation_overview_priority} top ON n.nid = top.tnid AND top.$language_field <> %d
438 ". implode(' ', $query['join']) ."
439 WHERE (n.nid = n.tnid OR n.tnid = 0) AND n.language NOT IN ('', '%s') AND n.language IS NOT NULL
440 AND ". implode(' AND ', $query['where']);
441 // We need to put the priority and language that we use as an argument early
442 // in the query at the beginning of the arguments list.
443 $args = array_merge(array($language, $language, TRANSLATION_OVERVIEW_IGNORE, $language), $query['where_args']);
444 $rows = array();
445 $result = pager_query(db_rewrite_sql($sql), $rows_per_page, 0, db_rewrite_sql($count_sql), $args);
446 while ($n = db_fetch_object($result)) {
447 $node = node_load($n->nid);
448 $translation = empty($n->translation_nid) ? NULL : node_load($n->translation_nid);
449 $rows[] = array(
450 array('data' => node_access('view', $node) ? l(translation_overview_trimmed_title($node, 30), 'node/'. $node->nid, array('attributes' => array('title' => $node->title))) : translation_overview_trimmed_title($node, 30)),
451 array('data' => translation_overview_translation_link($node, $translation, $language, TRUE), 'class' => 'status'),
452 array('data' => isset($node_types[$node->type]) ? $node_types[$node->type] : check_plain($node->type)),
453 array('data' => isset($languages[$node->language]) ? $languages[$node->language]->name : check_plain($node->language)),
454 array('data' => format_date($node->created, 'custom', 'j M Y')),
455 );
456 }
457
458 return drupal_get_form('translation_overview_filter_form')
459 . theme('table', $header, $rows, array('class' => 'trov'))
460 . theme('pager', NULL, $rows_per_page);
461 }

  ViewVC Help
Powered by ViewVC 1.1.2