Posted by edward.peters on July 24, 2008 at 9:27am
| Project: | Translation Overview |
| Version: | 6.x-1.x-dev |
| Component: | Code |
| Category: | bug report |
| Priority: | normal |
| Assigned: | Unassigned |
| Status: | closed (fixed) |
Issue Summary
I am really keen on this module, a fabulous one! But like others I am getting error messages which seem to be different. A screen full of stuff which ends with:
Warning: call_user_func_array() [function.call-user-func-array]: First argument is expected to be a valid callback, 'translation_overview_language_page' was given in
*\includes\menu.inc on line 346
Comments
#1
It was exciting to see a new release of this module yesterday, but disappointing to find that the errors I am getting persist in the latest version. Any chance of some feedback on what I can do?
#2
Same here!!!
I have the module (translation_overview-6.x-1.2) installed on drupal-6.3 (latest).
When i check "admin/content/translation_overview" i get this on screen instead of what expected to show (the interface):
t('status'), 'options' => array( 'status-1' => t('Published'), 'status-0' => t('Not published'), 'promote-1' => t('Promoted'), 'promote-0' => t('Not promoted'), 'sticky-1' => t('Sticky'), 'sticky-0' => t('Not sticky'), 'translate-0' => t('Up to date translation'), 'translate-1' => t('Outdated translation'), ), ); $filters['type'] = array( 'title' => t('type'), 'options' => translation_overview_node_types(), ); // The taxonomy filter if ($taxonomy = module_invoke('taxonomy', 'form_all', 1)) { $filters['category'] = array('title' => t('category'), 'options' => $taxonomy); } return $filters; } /** * Return form for node administration filters. * * This is a fork of node_filter_form(). */ function translation_overview_filter_form() { // We reuse a bunch of the node.module's stuff. module_load_include('inc', 'node', 'node.admin'); $session = &$_SESSION['translation_overview_filter']; $session = is_array($session) ? $session : array(); $filters = translation_overview_node_filters(); $i = 0; $form['filters'] = array( '#type' => 'fieldset', '#title' => t('Show only items where'), '#theme' => 'node_filters', ); $form['#submit'][] = 'translation_overview_filter_form_submit'; foreach ($session as $filter) { list($type, $value) = $filter; if ($type == 'category') { // Load term name from DB rather than search and parse options array. $value = module_invoke('taxonomy', 'get_term', $value); $value = $value->name; } else { $value = $filters[$type]['options'][$value]; } if ($i++) { $form['filters']['current'][] = array('#value' => t('and where %a is %b', array('%a' => $filters[$type]['title'], '%b' => $value))); } else { $form['filters']['current'][] = array('#value' => t('%a is %b', array('%a' => $filters[$type]['title'], '%b' => $value))); } if (in_array($type, array('type', 'language'))) { // Remove the option if it is already being filtered on. unset($filters[$type]); } } foreach ($filters as $key => $filter) { $names[$key] = $filter['title']; $form['filters']['status'][$key] = array('#type' => 'select', '#options' => $filter['options']); } $form['filters']['filter'] = array('#type' => 'radios', '#options' => $names, '#default_value' => 'status'); $form['filters']['buttons']['submit'] = array('#type' => 'submit', '#value' => (count($session) ? t('Refine') : t('Filter'))); if (count($session)) { $form['filters']['buttons']['undo'] = array('#type' => 'submit', '#value' => t('Undo')); $form['filters']['buttons']['reset'] = array('#type' => 'submit', '#value' => t('Reset')); } drupal_add_js('misc/form.js', 'core'); return $form; } /** * Process result from node administration filter form. * * This is a fork of node_filter_form(). */ function translation_overview_filter_form_submit($form, &$form_state) { $filters = translation_overview_node_filters(); switch ($form_state['values']['op']) { case t('Filter'): case t('Refine'): if (isset($form_state['values']['filter'])) { $filter = $form_state['values']['filter']; // Flatten the options array to accommodate hierarchical/nested options. $flat_options = form_options_flatten($filters[$filter]['options']); if (isset($flat_options[$form_state['values'][$filter]])) { $_SESSION['translation_overview_filter'][] = array($filter, $form_state['values'][$filter]); } } break; case t('Undo'): array_pop($_SESSION['translation_overview_filter']); break; case t('Reset'): $_SESSION['translation_overview_filter'] = array(); break; } } /** * Build the where clause for a filtered query. * * This is a fork of node_filter_form_submit(). */ function translation_overview_build_filter_query() { $filters = translation_overview_node_filters(); // Build query $join = $where = $args = array(); foreach ($_SESSION['translation_overview_filter'] as $index => $filter) { list($key, $value) = $filter; switch ($key) { case 'status': // Note: no exploitable hole as $key/$value have already been checked when submitted list($key, $value) = explode('-', $value, 2); $where['status'] = 'n.'. $key .' = %d'; break; case 'category': $table = "tn$index"; $where[$table] = "$table.tid = %d"; $join[$table] = "INNER JOIN {term_node} $table ON n.nid = $table.nid "; break; case 'type': $where['type'] = "n.type = '%s'"; break; } $args[] = $value; } // Make sure we limit it to translation enabled types. if (!isset($where['type'])) { $types = array_keys(translation_overview_node_types()); $where[] = 'n.type IN ('. db_placeholders($types, 'varchar') .')'; $args = array_merge($args, $types); } return array('where' => $where, 'join' => $join, 'args' => $args); } /** * Translation overview page. * * Current assumptions: * - translated node's status is synchronized via the i18n_sync module. */ function translation_overview_overview_page() { drupal_add_css(drupal_get_path('module', 'translation_overview') .'/translation_overview.css'); $rows_per_page = 30; // Get a list of the enabled languages $languages = array(); foreach (language_list() as $key => $language) { if ($language->enabled) { $languages[$key] = $language->language; } } // Sort the list so the order matches the menu items. asort($languages); $header = array( array('field' => 'n.title', 'data' => t('Title'), 'sort' => 'asc'), array('field' => 'n.type', 'data' => t('Type')), array('field' => 'n.created', 'data' => t('Created')), ); foreach ($languages as $key => $language_name) { $header[] = array('data' => str_replace('-', '', $language_name), 'class' => 'translation-overview-lang'); } $query = translation_overview_build_filter_query(); $sql = "SELECT n.nid, n.title, n.type, n.tnid, n.status, n.created, n.language, n.translate FROM {node} n ". implode(' ', $query['join']) ." WHERE (n.nid = n.tnid OR n.tnid = 0) AND n.language <> '' AND n.language IS NOT NULL AND ". implode(' AND ', $query['where']) . tablesort_sql($header); $rows = array(); $result = pager_query(db_rewrite_sql($sql), $rows_per_page, 0, NULL, $query['args']); while ($node = db_fetch_object($result)) { // Shorten down the title so the table isn't too wide. $title = $node->title; if (drupal_strlen($title) > 20) { $title = drupal_substr($title, 0, 15) .'...'; } $row = array( array('data' => l($title, 'node/'. $node->nid, array('attributes' => array('title' => $node->title)))), array('data' => check_plain($node->type)), array('data' => format_date($node->created, 'custom', 'j M Y')), ); // Load the node's translations and then fill in the table with the status. $translations = (array) translation_node_get_translations($node->tnid); foreach ($languages as $language) { $translation_nid = empty($translations[$language]->nid) ? NULL : $translations[$language]->nid; $row[$language] = array( 'data' => translation_overview_translation_link($node, $translation_nid, $language, FALSE), 'class' => 'translation-overview-status', ); } $rows[] = $row; } return drupal_get_form('translation_overview_filter_form') . theme('table', $header, $rows) . theme('pager', NULL, $rows_per_page); } function translation_overview_language_page($language) { $rows_per_page = 30; $types = array_keys(translation_overview_node_types()); $header = array( array('field' => 'n.title', 'data' => t('Title')), array('field' => 'n.type', 'data' => t('Type')), array('field' => 'n.status', 'data' => t('Status')), array('field' => 'n.language', 'data' => t('Language')), array('field' => 'n.created', 'data' => t('Created')), array('field' => 'translation_status', 'data' => t('Translated'), 'sort' => 'asc'), ); // We want to sort the nodes by the status so we have to resort to this SQL // CASE statement. // NOTE: the '0 AS i18n' is a little hack to prevent i18n from re-writing our // query. $rows = array(); $query = translation_overview_build_filter_query(); $sql = "SELECT n.nid, n.title, n.type, n.language, n.status, n.created, n.tnid, nt.nid AS t_nid, CASE WHEN n.language = '%s' THEN '4 LOCAL' WHEN nt.translate = 0 THEN '3 DONE' WHEN nt.tnid IS NULL THEN '2 MISS' WHEN n.nid = n.tnid THEN '1 OLD' ELSE 'unknown' END AS translation_status, 0 AS i18n FROM {node} n LEFT JOIN {node} nt ON n.nid = nt.tnid AND nt.language = '%s' ". implode(' ', $query['join']) ." WHERE (n.nid = n.tnid OR n.tnid = 0) AND n.language <> '' AND n.language IS NOT NULL AND ". implode(' AND ', $query['where']) . tablesort_sql($header); // We need to put the language that we use as an argument early in the query // at the beginning of the arguments list. array_unshift($query['args'], $language); array_unshift($query['args'], $language); $rows = array(); $result = pager_query(db_rewrite_sql($sql), $rows_per_page, 0, NULL, $query['args']); while ($node = db_fetch_object($result)) { // Shorten down the title $title = $node->title; if (drupal_strlen($title) > 25) { $title = drupal_substr($title, 0, 20) .'...'; } $rows[] = array( l($title, 'node/'. $node->nid, array('attributes' => array('title' => $node->title))), check_plain($node->type), empty($node->status) ? t('Unpublished') : t('Published'), $node->language, format_date($node->created, 'custom', 'j M Y'), translation_overview_translation_link($node, $node->t_nid, $language, TRUE), ); } return drupal_get_form('translation_overview_filter_form') . theme('table', $header, $rows) . theme('pager', NULL, $rows_per_page); }
And also i get an error:
warning: call_user_func_array() [function.call-user-func-array]: First argument is expected to be a valid callback, 'translation_overview_overview_page' was given in ../includes/menu.inc on line 346.What can i do?!
#3
Simple fix: In translation_overview.pages.inc, line #1, change
<?to<?php#4
Thank a lot raspberryman, i fix the translation_overview.pages.inc as you told me.
I used to have as a rule NOT to play around with any final revisions but seems that the work is not finished yet.
I indeed get the Translation overview now under admin/content/translation_overview but still saying:
warning: Invalid argument supplied for foreach() in sites/all/modules/translation_overview/translation_overview.pages.inc on line 137.
So i think the code still needs review!!
Any help?
#5
Thanks for this. It got rid of the main error messages.
However, there is a white screen of death when filtering on various options, and the server log reports:
PHP Warning: Cannot modify header information - headers already sent by (output started at */sites/all/modules/translation_overview/translation_overview.pages.inc: 1) in */includes/common.inc on line 319.
Never mind, it more or less works now. Thanks!
#6
Hi Peters,
Indeed it works as you say, or i could say at last it works. But still giving the "
warning: Invalid argument supplied for foreach() in */sites/all/modules/translation_overview/translation_overview.pages.inc on line 137" when you visit admin/content/translation_overview for the first time just after logging. But when you visit it again, it doesn't!! I log out, log in then visit again, i have the same error!! Strange!!Speaking about it, i tried filtering on various options as you mentioned —which i could not do that— but you are allowed only to check one at a time from the check box & the menu, click Filter and get results, then filter again if you want to get better results, and so on… but i never get white screens, so it's weird!!
More problems for the module creator to fix.
It works now at least, getting full info about what you have on your site, translated, out of date or untranslated.
Hope drewish reads us and soon fix all these problems giving us new Official releases.
#7
Whoa. A bunch of different issues have crept into this issue.
The fix for #2 (as per #3), I have attached as a patch (which should apply to both HEAD and DRUPAL-6--1). A workaround would be enabling
short_open_tagin php.ini.@ errement: Note that putting one in the "Assigned" box means that you take on the responsibility of getting the issue fixed. I'm assuming this wasn't what you meant by doing it, so I took the liberty of unassigning you. Feel free to re-assign if you did mean it.
Also, there are a bunch of other warnings and error messages floating about here, but I feel they would be best taken care of in their own issues.
#8
Fresco,
Sorry & thanq!!
#9
thanks, sorry I hadn't seen this for some reason I wasn't subscribed to this issue queue.
committed to the DRUPAL-6--1 branch.
#10
also committed to HEAD.
#11
Automatically closed -- issue fixed for two weeks with no activity.