diff --git a/core/modules/locale/locale.module b/core/modules/locale/locale.module index cfc4931..14b7788 100644 --- a/core/modules/locale/locale.module +++ b/core/modules/locale/locale.module @@ -184,9 +184,21 @@ function locale_menu() { $items['admin/reports/translations'] = array( 'title' => 'Available translation updates', 'description' => 'Get a status report about available interface translations for your installed modules and themes.', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('locale_translation_status_form'), + 'page callback' => 'locale_translation_update_status', + 'access arguments' => array('translate interface'), + 'file' => 'locale.pages.inc', + ); + $items['admin/reports/translations/list'] = array( + 'title' => 'List', 'access arguments' => array('translate interface'), + 'type' => MENU_DEFAULT_LOCAL_TASK, + ); + $items['admin/reports/translations/settings'] = array( + 'title' => 'Settings', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('locale_translation_admin_settings'), + 'access arguments' => array('administer site configuration'), + 'type' => MENU_LOCAL_TASK, 'file' => 'locale.pages.inc', ); $items['admin/reports/translations/check'] = array( @@ -221,6 +233,14 @@ function locale_theme() { 'render element' => 'form', 'file' => 'locale.pages.inc', ), + 'locale_translation_update_status' => array( + 'variables' => array('languages' => NULL, 'projects' => NULL, 'updates' => NULL, 'last' => NULL), + 'file' => 'locale.pages.inc', + ), + 'locale_translation_language_updates' => array( + 'variables' => array('updates' => NULL), + 'file' => 'locale.pages.inc', + ), ); } diff --git a/core/modules/locale/locale.pages.inc b/core/modules/locale/locale.pages.inc index 2386fdb..3e18e1c 100644 --- a/core/modules/locale/locale.pages.inc +++ b/core/modules/locale/locale.pages.inc @@ -471,109 +471,99 @@ function locale_translation_manual_status() { * * @see locale_menu() */ -function locale_translation_status_form($form, &$form_state) { +function locale_translation_update_status() { module_load_include('compare.inc', 'locale'); //locale_translation_flush_projects(); $projects = locale_translation_get_projects(); $languages = locale_translatable_language_list(); - $status = state()->get('locale_translation_status'); if (!$languages) { - drupal_set_message(t('No translatable languages available. Add language first.', array('@add_lanuage' => url('admin/config/regional/language'))), 'warning'); + $build['add_language']['#markup'] = t('No translatable languages available. Add language first.', array( + '@add_lanuage' => url('admin/config/regional/language') + )); } + else { + // === Start of temporay code. For development only === + $last_update = state()->get('locale_translation_status_last_update'); + $markup = '
'; + $markup .= $last_update ? t('Last checked: @time ago', array('@time' => format_interval(REQUEST_TIME - $last_update))) : t('Last checked: never'); + $markup .= ' (' . l(t('Check manually'), 'admin/reports/translations/check', array('query' => drupal_get_destination())) . ')'; + $markup .= '
'; + $build['last_checked'] = array( + '#markup' => $markup, + ); - // === Start of temporay code. For development only === - $last = state()->get('locale_translation_status_last_update'); - $markup = ''; - $markup .= $last ? t('Last checked: @time ago', array('@time' => format_interval(REQUEST_TIME - $last))) : t('Last checked: never'); - $markup .= ' (' . l(t('Check manually'), 'admin/reports/translations/check', array('query' => drupal_get_destination())) . ')'; - $markup .= '
'; - $form['last_checked'] = array( - '#markup' => $markup, - ); + $status = _locale_translation_update_status(); + $build['status']['#markup'] = theme('locale_translation_update_status', array( + 'languages' => $languages, + 'projects' => $projects, + 'updates' => $status['updates'], + 'last' => $status['last'], + )); + if ($status['updates']) { + $build['update'] = drupal_get_form('locale_translation_status_form'); + } + } - $table_header = array(t('Project'), t('Version'), t('Status'), t('Current version'), t('Timestamp'), t('Recommended version'), t('Timestamp'), t('Source')); - $rows = array(); - foreach ($projects as $name => $project) { - foreach ($languages as $langcode => $language) { - if (isset($status[$name][$langcode])) { - $source = $status[$name][$langcode]; - $row = array( - 'project' => $name, - 'version' => $source->version, - 'status' => isset($source->type) ? $source->type == 'current' ? t('Up to date') : t('Translations available') : t('Unknown'), - 'current version' => '', - 'current timestamp' => '', - 'recommended version' => '', - 'recommended timestamp' => '', - 'recommended source' => '', - ); - if (isset($source->files['current'])) { - $current = $source->files['current']; - $row['current version'] = $current->version; - $row['current timestamp'] = format_date($current->timestamp, 'custom', 'j M - G:i:s'); + return $build; +} + +/** + * Compute available updates per language. + */ +function _locale_translation_update_status() { + $updates = $last = $sources = array(); + $status = state()->get('locale_translation_status') ?: array(); + foreach ($status as $name => $project_status) { + foreach ($project_status as $langcode => $source) { + if (isset($last[$langcode])) { + $last_updated = $last[$langcode]['updated']; + $last_available = $last[$langcode]['available']; + } + else { + $last_updated = $last_available = 0; + } + $available = NULL; + if (isset($source->type)) { + if ($source->type == 'current') { + $last_updated = max($last_updated, $source->timestamp); } - if ($row['status'] == t('Translations available')) { - $available = $source->files[$source->type]; - $row['recommended version'] = $available->version; - $row['recommended timestamp'] = format_date($available->timestamp, 'custom', 'j M - G:i:s'); - $row['recommended source'] = $available->type; + elseif ($source->type == 'remote') { + $available = $source->files['remote']; + $updates[$langcode]['remote'][$name] = $available; + } + elseif ($source->type == 'local') { + $available = $source->files['local']; + $updates[$langcode]['local'][$name] = $available; } } - else { - $row = array( - 'project' => $project, - 'version' => $source->version, - 'status' => t('Unknown'), - 'current version' => '', - 'current timestamp' => '', - 'recommended version' => '', - 'recommended timestamp' => '', - 'recommended source' => '', - ); + if ($available) { + $last_available = max($last_available, $available->timestamp); + $sources[] = $source; } - $rows[] = $row; + $last[$langcode]['updated'] = $last_updated; + $last[$langcode]['available'] = $last_available; } } - $form['table'] = array( - '#markup' => theme('table', array('header' => $table_header, 'rows' => $rows)), - ); - // @todo Calculate and display the translation status here. See the follow-up - // issue for translation interface: http://drupal.org/node/1804702 - // This form content is temporary and required to get the tests working. - $options = array(); - foreach ($projects as $name => $project) { - $options[$name] = $project->name; - } - $form['projects'] = array( - '#title' => t('Projects'), - '#type' => 'checkboxes', - '#options' => $options, - '#default_value' => drupal_map_assoc(array_keys($options)), - '#required' => TRUE, - ); + return array('updates' => $updates, 'last' => $last, 'sources' => $sources); +} + - $options = array(); - foreach ($languages as $langcode => $language) { - $options[$langcode] = $language->name; - } - $form['langcodes'] = array( - '#title' => t('Languages'), - '#type' => 'checkboxes', - '#options' => $options, - '#default_value' => drupal_map_assoc(array_keys($options)), - '#required' => TRUE, - ); - // === End of temporay code. For development only === +/** + * Page callback: Display the current translation status. + * + * @see locale_menu() + */ +function locale_translation_status_form($form, &$form_state) { $form['actions'] = array( - '#type' => 'actions' + '#type' => 'actions' ); $form['actions']['submit'] = array( - '#type' => 'submit', - '#value' => t('Update') + '#type' => 'submit', + '#value' => t('Update') ); return $form; } @@ -582,9 +572,6 @@ function locale_translation_status_form($form, &$form_state) { * Form submission handler for locale_translation_status(). */ function locale_translation_status_form_submit($form, &$form_state) { - $langcodes = array_filter($form_state['values']['langcodes']); - $projects = array_filter($form_state['values']['projects']); - // If the status was updated recently we can immediately start updating. If // the status is not expired we will get the status first. $last_checked = state()->get('locale_translation_status_last_update'); @@ -594,22 +581,85 @@ function locale_translation_status_form_submit($form, &$form_state) { } else { module_load_include('fetch.inc', 'locale'); - $status = state()->get('locale_translation_status'); - // Use only the selected projects and languages for update. - $sources = array(); - foreach($projects as $project) { - foreach ($langcodes as $langcode) { - if (isset($status[$project][$langcode])) { - $sources[] = $status[$project][$langcode]; - } - } - } - $batch = locale_translation_batch_fetch_build($sources); + $status = _locale_translation_update_status(); + $batch = locale_translation_batch_fetch_build($status['sources']); batch_set($batch); } } /** + * Settings form for locale updates. + */ +function locale_translation_admin_settings($form, &$form_state) { + $config = config('locale.settings'); + $form['options'] = array( + '#type' => 'fieldset', + '#title' => t('Update options'), + '#tree' => TRUE, + ); + $form['options']['use_source'] = array( + '#title' => t('Update source'), + '#type' => 'select', + '#options' => array( + 'remote_and_local' => t('Remote and local'), + ), + '#default_value' => $config->get('translation.use_source'), + ); + $form['options']['default_server_pattern'] = array( + '#type' => 'textfield', + '#title' => t('Server pattern'), + '#default_value' => $config->get('translation.default_server_pattern'), + ); + $form['options']['overwrite_customized'] = array( + ); + $form['options']['overwrite_not_customized'] = array( + ); + $form['options']['check_disabled_modules'] = array( + '#title' => t('Update disabled modules'), + '#type' => 'checkbox', + '#default_value' => $config->get('translation.check_disabled_modules'), + ); + // Select languages and projects. + module_load_include('compare.inc', 'locale'); + $projects = locale_translation_get_projects(); + $languages = locale_translatable_language_list(); + $options = array(); + foreach ($languages as $langcode => $language) { + $options[$langcode] = $language->name; + } + $form['langcodes'] = array( + '#title' => t('Languages'), + '#type' => 'checkboxes', + '#options' => $options, + '#default_value' => drupal_map_assoc(array_keys($options)), + '#required' => TRUE, + ); + $options = array(); + foreach ($projects as $name => $project) { + $options[$name] = $project->name; + } + $form['projects'] = array( + '#title' => t('Projects'), + '#type' => 'checkboxes', + '#options' => $options, + '#default_value' => drupal_map_assoc(array_keys($options)), + '#required' => TRUE, + ); + return system_settings_form($form); +} + +/** + * Submit settings for locale_updates. + */ +function locale_translation_admin_settings_submit($form, &$form_state) { + $config = config('locale.settings'); + foreach ($from_state['values']['options'] as $name => $value) { + $config->set('translation.' . $name, $value); + } + $config->save(); +} + +/** * Default theme function for translation edit form. */ function theme_locale_translate_edit_form_strings($variables) { @@ -643,3 +693,84 @@ function theme_locale_translate_edit_form_strings($variables) { $output .= theme('pager'); return $output; } + +/** + * Translation update status. + */ +function theme_locale_translation_update_status($variables) { + $languages = $variables['languages']; + $projects = $variables['projects']; + $updates = $variables['updates']; + $last = $variables['last']; + $total_strings = locale_storage()->countStrings(); + $translations = locale_storage()->countTranslations(); + $rows = array(); + $local = $remote = 0; + foreach ($languages as $langcode => $language) { + $last_updated = isset($last[$langcode]) ? $last[$langcode]['updated'] : 0; + + // Generate row content for language. + if ($last_updated && empty($updates[$langcode])) { + $class = 'ok'; + $legend = t('Up to date'); + $icon = theme('image', array('uri' => 'core/misc/watchdog-ok.png', 'width' => 18, 'height' => 18, 'alt' => t('ok'), 'title' => t('ok'))); + } + elseif (!empty($updates[$langcode])) { + $class = 'warning'; + $legend = t('Update available'); + $icon = theme('image', array('uri' => 'core/misc/watchdog-warning.png', 'width' => 18, 'height' => 18, 'alt' => t('warning'), 'title' => t('warning'))); + } + else { + $class = 'unknown'; + $legend = t('Unknown'); + $icon = theme('image', array('uri' => 'core/misc/watchdog-warning.png', 'width' => 18, 'height' => 18, 'alt' => t('warning'), 'title' => t('warning'))); + } + + + $row['language'] = '