Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
Total | |
0.00% |
0 / 1 |
|
0.00% |
0 / 9 |
CRAP | |
0.00% |
0 / 165 |
TranslationStatusForm | |
0.00% |
0 / 1 |
|
0.00% |
0 / 9 |
1482 | |
0.00% |
0 / 165 |
create | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 5 |
|||
__construct | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 3 |
|||
getFormId | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 2 |
|||
buildForm | |
0.00% |
0 / 1 |
132 | |
0.00% |
0 / 35 |
|||
anonymous function | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 2 |
|||
prepareUpdateData | |
0.00% |
0 / 1 |
132 | |
0.00% |
0 / 26 |
|||
createInfoString | |
0.00% |
0 / 1 |
56 | |
0.00% |
0 / 13 |
|||
validateForm | |
0.00% |
0 / 1 |
6 | |
0.00% |
0 / 4 |
|||
submitForm | |
0.00% |
0 / 1 |
12 | |
0.00% |
0 / 19 |
<?php | |
/** | |
* @file | |
* Contains \Drupal\locale\Form\TranslationStatusForm. | |
*/ | |
namespace Drupal\locale\Form; | |
use Drupal\Core\Extension\ModuleHandlerInterface; | |
use Drupal\Core\Form\FormBase; | |
use Drupal\Core\Form\FormStateInterface; | |
use Drupal\Core\State\StateInterface; | |
use Symfony\Component\DependencyInjection\ContainerInterface; | |
/** | |
* Provides a translation status form. | |
*/ | |
class TranslationStatusForm extends FormBase { | |
/** | |
* The module handler service. | |
* | |
* @var \Drupal\Core\Extension\ModuleHandlerInterface | |
*/ | |
protected $moduleHandler; | |
/** | |
* The Drupal state storage service. | |
* | |
* @var \Drupal\Core\State\StateInterface | |
*/ | |
protected $state; | |
/** | |
* {@inheritdoc} | |
*/ | |
public static function create(ContainerInterface $container) { | |
return new static( | |
$container->get('module_handler'), | |
$container->get('state') | |
); | |
} | |
/** | |
* Constructs a TranslationStatusForm object. | |
* | |
* @param ModuleHandlerInterface $module_handler | |
* A module handler. | |
* @param \Drupal\Core\State\StateInterface $state | |
* The state service. | |
*/ | |
public function __construct(ModuleHandlerInterface $module_handler, StateInterface $state) { | |
$this->moduleHandler = $module_handler; | |
$this->state = $state; | |
} | |
/** | |
* {@inheritdoc} | |
*/ | |
public function getFormId() { | |
return 'locale_translation_status_form'; | |
} | |
/** | |
* Form builder for displaying the current translation status. | |
* | |
* @ingroup forms | |
*/ | |
public function buildForm(array $form, FormStateInterface $form_state) { | |
$languages = locale_translatable_language_list(); | |
$status = locale_translation_get_status(); | |
$options = array(); | |
$languages_update = array(); | |
$languages_not_found = array(); | |
$projects_update = array(); | |
// Prepare information about projects which have available translation | |
// updates. | |
if ($languages && $status) { | |
$updates = $this->prepareUpdateData($status); | |
// Build data options for the select table. | |
foreach ($updates as $langcode => $update) { | |
$title = $languages[$langcode]->getName(); | |
$locale_translation_update_info = array('#theme' => 'locale_translation_update_info'); | |
foreach (array('updates', 'not_found') as $update_status) { | |
if (isset($update[$update_status])) { | |
$locale_translation_update_info['#' . $update_status] = $update[$update_status]; | |
} | |
} | |
$options[$langcode] = array( | |
'title' => array( | |
'data' => array( | |
'#title' => $title, | |
'#plain_text' => $title, | |
), | |
), | |
'status' => array( | |
'class' => array('description', 'priority-low'), | |
'data' => $locale_translation_update_info, | |
), | |
); | |
if (!empty($update['not_found'])) { | |
$languages_not_found[$langcode] = $langcode; | |
} | |
if (!empty($update['updates'])) { | |
$languages_update[$langcode] = $langcode; | |
} | |
} | |
// Sort the table data on language name. | |
uasort($options, function ($a, $b) { | |
return strcasecmp($a['title']['data']['#title'], $b['title']['data']['#title']); | |
}); | |
$languages_not_found = array_diff($languages_not_found, $languages_update); | |
} | |
$last_checked = $this->state->get('locale.translation_last_checked'); | |
$form['last_checked'] = array( | |
'#theme' => 'locale_translation_last_check', | |
'#last' => $last_checked, | |
); | |
$header = array( | |
'title' => array( | |
'data' => $this->t('Language'), | |
'class' => array('title'), | |
), | |
'status' => array( | |
'data' => $this->t('Status'), | |
'class' => array('status', 'priority-low'), | |
), | |
); | |
if (!$languages) { | |
$empty = $this->t('No translatable languages available. <a href=":add_language">Add a language</a> first.', array( | |
':add_language' => $this->url('entity.configurable_language.collection'), | |
)); | |
} | |
elseif ($status) { | |
$empty = $this->t('All translations up to date.'); | |
} | |
else { | |
$empty = $this->t('No translation status available. <a href=":check">Check manually</a>.', array( | |
':check' => $this->url('locale.check_translation'), | |
)); | |
} | |
// The projects which require an update. Used by the _submit callback. | |
$form['projects_update'] = array( | |
'#type' => 'value', | |
'#value' => $projects_update, | |
); | |
$form['langcodes'] = array( | |
'#type' => 'tableselect', | |
'#header' => $header, | |
'#options' => $options, | |
'#default_value' => $languages_update, | |
'#empty' => $empty, | |
'#js_select' => TRUE, | |
'#multiple' => TRUE, | |
'#required' => TRUE, | |
'#not_found' => $languages_not_found, | |
'#after_build' => array('locale_translation_language_table'), | |
); | |
$form['#attached']['library'][] = 'locale/drupal.locale.admin'; | |
$form['actions'] = array('#type' => 'actions'); | |
if ($languages_update) { | |
$form['actions']['submit'] = array( | |
'#type' => 'submit', | |
'#value' => $this->t('Update translations'), | |
); | |
} | |
return $form; | |
} | |
/** | |
* Prepare information about projects with available translation updates. | |
* | |
* @param array $status | |
* Translation update status as an array keyed by Project ID and langcode. | |
* | |
* @return array | |
* Translation update status as an array keyed by language code and | |
* translation update status. | |
*/ | |
protected function prepareUpdateData(array $status) { | |
$updates = array(); | |
// @todo Calling locale_translation_build_projects() is an expensive way to | |
// get a module name. In follow-up issue | |
// https://www.drupal.org/node/1842362 the project name will be stored to | |
// display use, like here. | |
$this->moduleHandler->loadInclude('locale', 'compare.inc'); | |
$project_data = locale_translation_build_projects(); | |
foreach ($status as $project_id => $project) { | |
foreach ($project as $langcode => $project_info) { | |
// No translation file found for this project-language combination. | |
if (empty($project_info->type)) { | |
$updates[$langcode]['not_found'][] = array( | |
'name' => $project_info->name == 'drupal' ? $this->t('Drupal core') : $project_data[$project_info->name]->info['name'], | |
'version' => $project_info->version, | |
'info' => $this->createInfoString($project_info), | |
); | |
} | |
// Translation update found for this project-language combination. | |
elseif ($project_info->type == LOCALE_TRANSLATION_LOCAL || $project_info->type == LOCALE_TRANSLATION_REMOTE) { | |
$local = isset($project_info->files[LOCALE_TRANSLATION_LOCAL]) ? $project_info->files[LOCALE_TRANSLATION_LOCAL] : NULL; | |
$remote = isset($project_info->files[LOCALE_TRANSLATION_REMOTE]) ? $project_info->files[LOCALE_TRANSLATION_REMOTE] : NULL; | |
$recent = _locale_translation_source_compare($local, $remote) == LOCALE_TRANSLATION_SOURCE_COMPARE_LT ? $remote : $local; | |
$updates[$langcode]['updates'][] = array( | |
'name' => $project_info->name == 'drupal' ? $this->t('Drupal core') : $project_data[$project_info->name]->info['name'], | |
'version' => $project_info->version, | |
'timestamp' => $recent->timestamp, | |
); | |
} | |
} | |
} | |
return $updates; | |
} | |
/** | |
* Provides debug info for projects in case translation files are not found. | |
* | |
* Translations files are being fetched either from Drupal translation server | |
* and local files or only from the local filesystem depending on the | |
* "Translation source" setting at admin/config/regional/translate/settings. | |
* This method will produce debug information including the respective path(s) | |
* based on this setting. | |
* | |
* @param array $project_info | |
* An array which is the project information of the source. | |
* | |
* @return string | |
* The string which contains debug information. | |
*/ | |
protected function createInfoString($project_info) { | |
$remote_path = isset($project_info->files['remote']->uri) ? $project_info->files['remote']->uri : FALSE; | |
$local_path = isset($project_info->files['local']->uri) ? $project_info->files['local']->uri : FALSE; | |
if (locale_translation_use_remote_source() && $remote_path && $local_path) { | |
return $this->t('File not found at %remote_path nor at %local_path', array( | |
'%remote_path' => $remote_path, | |
'%local_path' => $local_path, | |
)); | |
} | |
elseif ($local_path) { | |
return $this->t('File not found at %local_path', array('%local_path' => $local_path)); | |
} | |
return $this->t('Translation file location could not be determined.'); | |
} | |
/** | |
* {@inheritdoc} | |
*/ | |
public function validateForm(array &$form, FormStateInterface $form_state) { | |
// Check if a language has been selected. 'tableselect' doesn't. | |
if (!array_filter($form_state->getValue('langcodes'))) { | |
$form_state->setErrorByName('', $this->t('Select a language to update.')); | |
} | |
} | |
/** | |
* {@inheritdoc} | |
*/ | |
public function submitForm(array &$form, FormStateInterface $form_state) { | |
$this->moduleHandler->loadInclude('locale', 'fetch.inc'); | |
$this->moduleHandler->loadInclude('locale', 'bulk.inc'); | |
$langcodes = array_filter($form_state->getValue('langcodes')); | |
$projects = array_filter($form_state->getValue('projects_update')); | |
// Set the translation import options. This determines if existing | |
// translations will be overwritten by imported strings. | |
$options = _locale_translation_default_update_options(); | |
// If the status was updated recently we can immediately start fetching the | |
// translation updates. If the status is expired we clear it an run a batch to | |
// update the status and then fetch the translation updates. | |
$last_checked = $this->state->get('locale.translation_last_checked'); | |
if ($last_checked < REQUEST_TIME - LOCALE_TRANSLATION_STATUS_TTL) { | |
locale_translation_clear_status(); | |
$batch = locale_translation_batch_update_build(array(), $langcodes, $options); | |
batch_set($batch); | |
} | |
else { | |
// Set a batch to download and import translations. | |
$batch = locale_translation_batch_fetch_build($projects, $langcodes, $options); | |
batch_set($batch); | |
// Set a batch to update configuration as well. | |
if ($batch = locale_config_batch_update_components($options, $langcodes)) { | |
batch_set($batch); | |
} | |
} | |
} | |
} |