Commit 15f0171d authored by catch's avatar catch

Issue #1831530 by plach, YesCT: Entity translation UI in core (part 2).

parent 6e5d1a09
......@@ -33,8 +33,8 @@ public function entityFormAlter(array &$form, array &$form_state, EntityInterfac
function entityFormSave(array $form, array &$form_state) {
if ($this->getSourceLangcode($form_state)) {
$entity = translation_entity_form_controller($form_state)->getEntity($form_state);
// We need a redirect here, otherwise we would get an access denied page
// since the curret URL would be preserved and we would try to add a
// We need a redirect here, otherwise we would get an access denied page,
// since the current URL would be preserved and we would try to add a
// translation for a language that already has a translation.
$form_state['redirect'] = $this->getEditPath($entity);
}
......
......@@ -243,7 +243,7 @@ public function entityFormAlter(array &$form, array &$form_state, EntityInterfac
}
if ($language_widget) {
$form_langcode['#multilingual'] = TRUE;
$form['langcode']['#multilingual'] = TRUE;
}
$form['#process'][] = array($this, 'entityFormSharedElements');
......
......@@ -56,6 +56,9 @@ function translation_entity_schema() {
* Implements hook_install().
*/
function translation_entity_install() {
// Assign a fairly low weight to ensure our implementation of
// hook_module_implements_alter() is run among the last ones.
module_set_weight('translation_entity', 10);
language_negotiation_include();
language_negotiation_set(LANGUAGE_TYPE_CONTENT, array(LANGUAGE_NEGOTIATION_URL => 0));
}
......@@ -64,10 +67,14 @@ function translation_entity_install() {
* Implements hook_enable().
*/
function translation_entity_enable() {
$t_args = array(
'!language_url' => url('admin/config/regional/language'),
'!settings_url' => url('admin/config/regional/content-language'),
);
$message = t('Content translation has been enabled. To use content translation, <a href="!language_url">enable at least two languages</a> and <a href="!settings_url">enable translation</a> for <em>content types</em>, <em>taxonomy vocabularies</em>, <em>accounts</em>, or any other element you wish to translate.', $t_args);
// Translation works when at least two languages are enabled.
if (count(language_list()) < 2) {
$t_args = array('!language_url' => url('admin/config/regional/language'));
$message = t('Be sure to <a href="!language_url">enable at least two languages</a> to translate content.', $t_args);
drupal_set_message($message, 'warning');
}
// Point the user to the content translation settings.
$t_args = array('!settings_url' => url('admin/config/regional/content-language'));
$message = t('<a href="!settings_url">Enable translation</a> for <em>content types</em>, <em>taxonomy vocabularies</em>, <em>accounts</em>, or any other element you wish to translate.', $t_args);
drupal_set_message($message, 'warning');
}
......@@ -44,10 +44,27 @@ function translation_entity_help($path, $arg) {
}
}
/**
* Implements hook_module_implements_alter().
*/
function translation_entity_module_implements_alter(&$implementations, $hook) {
switch ($hook) {
// Move some of our hook implementations to the end of the list.
case 'menu_alter':
case 'entity_info_alter':
$group = $implementations['translation_entity'];
unset($implementations['translation_entity']);
$implementations['translation_entity'] = $group;
break;
}
}
/**
* Implements hook_language_type_info_alter().
*/
function translation_entity_language_types_info_alter(array &$language_types) {
// Make content language negotiation configurable by removing its predefined
// configuration.
unset($language_types[LANGUAGE_TYPE_CONTENT]['fixed']);
}
......@@ -176,30 +193,23 @@ function translation_entity_menu() {
* Implements hook_menu_alter().
*/
function translation_entity_menu_alter(array &$items) {
// Some menu loaders in the item paths might have been altered: we need to
// replace any menu loader with a plain % to check if base paths are still
// compatible.
$paths = array();
$regex = '|%[^/]+|';
foreach ($items as $path => $item) {
$path = preg_replace($regex, '%', $path);
$paths[$path] = $path;
}
// Check that the declared menu base paths are actually valid.
foreach (entity_get_info() as $entity_type => $info) {
if (translation_entity_enabled($entity_type)) {
$path = $info['menu_base_path'];
// If the base path is not defined or is not compatible with any defined
// one we cannot provide the translation UI for this entity type.
if (!isset($paths[preg_replace($regex, '%', $path)])) {
drupal_set_message(t('The entities of type %entity_type do not define a valid base path: it will not be possible to translate them.', array('%entity_type' => $info['label'])), 'warning');
// If the base path is not defined we cannot provide the translation UI
// for this entity type. In some cases the actual base path might not have
// a menu loader associated, hence we need to check also for the plain "%"
// variant. See for instance comment_menu().
if (!isset($items[$path]) && !isset($items[_translation_entity_menu_strip_loaders($path)])) {
unset(
$items["$path/translations"],
$items["$path/translations/add/%language"],
$items["$path/translations/add/%language/%language"],
$items["$path/translations/delete/%language"]
);
$t_args = array('@entity_type' => isset($info['label']) ? $info['label'] : $entity_type);
watchdog('entity translation', 'The entities of type @entity_type do not define a valid base path: it will not be possible to translate them.', $t_args, WATCHDOG_WARNING);
}
else {
$entity_position = count(explode('/', $path)) - 1;
......@@ -225,6 +235,19 @@ function translation_entity_menu_alter(array &$items) {
}
}
/**
* Strips out menu loaders from the given path.
*
* @param string $path
* The path to process.
*
* @return
* The given path where all the menu loaders are replaced with "%".
*/
function _translation_entity_menu_strip_loaders($path) {
return preg_replace('|%[^/]+|', '%', $path);
}
/**
* Access callback for the translation overview page.
*
......@@ -279,10 +302,10 @@ function translation_entity_library_info() {
}
/**
* Returns the key name used to store the configuration item.
* Returns the key name used to store the configuration setting.
*
* Based on the entity type and bundle, the variables used to store the
* configuration will have a common root name.
* Based on the entity type and bundle, the keys used to store configuration
* will have a common root name.
*
* @param string $entity_type
* The type of the entity the setting refers to.
......@@ -292,7 +315,7 @@ function translation_entity_library_info() {
* The name of the setting.
*
* @return string
* The key name of the configuration item.
* The key name of the configuration setting.
*
* @todo Generalize this logic so that it is available to any module needing
* per-bundle configuration.
......@@ -368,6 +391,34 @@ function translation_entity_enabled($entity_type, $bundle = NULL, $skip_handler
return $enabled && ($skip_handler || field_has_translation_handler($entity_type, 'translation_entity'));
}
/**
* Returns all the translatable entity types.
*
* @return array
* An array of entity types keyed by entity type.
*/
function translation_entity_types_translatable() {
$entity_types = &drupal_static(__FUNCTION__, array());
foreach (entity_get_info() as $entity_type => $info) {
if (translation_entity_enabled($entity_type)) {
// Lazy load router items.
if (!isset($items)) {
$items = menu_get_router();
}
// Check whether the required paths are defined. We need to strip out the
// menu loader and replace it with a plain "%" as router items have no
// menu loader in them.
$path = _translation_entity_menu_strip_loaders($info['menu_base_path']);
if (!empty($items[$path]) && !empty($items[$path . '/translations'])) {
$entity_types[$entity_type] = $entity_type;
}
}
}
return $entity_types;
}
/**
* Entity translation controller factory.
*
......@@ -507,12 +558,8 @@ function translation_entity_entity_load(array $entities, $entity_type) {
* The type of the entities.
*/
function translation_entity_load_translation_data(array $entities, $entity_type) {
$result = db_select('translation_entity', 'te')
->fields('te', array())
->condition('te.entity_type', $entity_type)
->condition('te.entity_id', array_keys($entities))
->execute();
$query = 'SELECT * FROM {translation_entity} te WHERE te.entity_type = :entity_type AND te.entity_id IN (:entity_id)';
$result = db_query($query, array(':entity_type' => $entity_type, ':entity_id' => array_keys($entities)));
foreach ($result as $record) {
$entity = $entities[$record->entity_id];
// @todo Declare these as entity (translation?) properties.
......@@ -604,21 +651,18 @@ function translation_entity_form_field_ui_field_settings_form_alter(array &$form
$field = $form['#field'];
$field_name = $field['field_name'];
$translatable = $field['translatable'];
$title = t('Users may translate this field.');
$label = t('Field translation');
if (field_has_data($field)) {
$path = "admin/config/regional/translation_entity/translatable/$field_name";
$status = $translatable ? $title : t('This field has data in existing content.');
$link_title = !$translatable ? t('Enable translation') : t('Disable translation');
$form['field']['translatable'] = array(
'message' => array(
'#markup' => $status . ' ',
),
'#type' => 'item',
'#title' => $label,
'#attributes' => array('class' => 'translatable'),
'link' => array(
'#type' => 'link',
'#title' => $link_title,
'#href' => $path,
'#prefix' => t('This field has data in existing content.') . ' ',
'#title' => !$translatable ? t('Enable translation') : t('Disable translation'),
'#href' => 'admin/config/regional/translation_entity/translatable/' . $field_name,
'#options' => array('query' => drupal_get_destination()),
'#access' => user_access('administer entity translation'),
),
......@@ -627,10 +671,12 @@ function translation_entity_form_field_ui_field_settings_form_alter(array &$form
else {
$form['field']['translatable'] = array(
'#type' => 'checkbox',
'#title' => $title,
'#title' => t('Users may translate this field.'),
'#default_value' => $translatable,
);
}
$form['field']['translatable']['#weight'] = 20;
}
/**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment