You are here

i18n_menu_hierarchy.module in Language Hierarchy 7

File

modules/i18n_menu_hierarchy/i18n_menu_hierarchy.module
View source
<?php

/**
 * Implements hook_menu_local_tasks_alter().
 */
function i18n_menu_hierarchy_menu_local_tasks_alter(&$data, $router_item, $root_path) {

  // Menu overview form.
  if ($root_path == 'admin/structure/menu/manage/%') {
    i18n_menu_hierarchy_menu_local_tasks_alter_overview_form($data, $router_item, $root_path);
  }
  elseif (in_array($root_path, array(
    'admin/structure/menu/manage/%/add',
    'admin/structure/menu/item/%',
  ))) {
    i18n_menu_hierarchy_menu_local_tasks_alter_menu_edit_item($data, $router_item, $root_path);
  }
}

/**
 * Alter local tasks for menu overview form.
 *
 * @see i18n_menu_hierarchy_menu_local_tasks_alter().
 */
function i18n_menu_hierarchy_menu_local_tasks_alter_overview_form(&$data, $router_item, $root_path) {
  $menu_name = $router_item['page_arguments'][1]['menu_name'];
  if (!i18n_menu_mode($menu_name, I18N_MODE_MULTIPLE)) {
    return;
  }
  $sql = 'SELECT ml.menu_name, ml.language FROM {menu_links} ml WHERE ml.menu_name = :menu_name';
  $menu_links = db_query($sql, array(
    ':menu_name' => $menu_name,
  ))
    ->fetchAll();
  $menu_languages = array(
    language_default('language'),
  );
  foreach ($menu_links as $menu_link) {
    if ($menu_link->language != LANGUAGE_NONE) {
      $menu_languages[] = $menu_link->language;
    }
  }
  $menu_languages = array_unique($menu_languages, SORT_REGULAR);
  $language_list = language_hierarchy_language_list();
  $default_language = $GLOBALS['language']->language;
  $selected_language = arg(6) && isset($language_list[arg(6)]) ? arg(6) : $default_language;
  $data['actions']['count'] += 1;
  $data['actions']['output'][0] = array(
    '#theme' => 'menu_local_task',
    '#link' => array(
      'title' => t('Add link'),
      'href' => 'admin/structure/menu/manage/' . $menu_name . '/add/' . $selected_language,
      'localized_options' => array(),
    ),
  );
  foreach ($menu_languages as $language) {
    if (isset($language_list[$language])) {
      $href = 'admin/structure/menu/manage/' . $menu_name;
      if ($default_language != $language) {
        $href .= '/list/' . $language;
      }

      // If there is only one translation then set count to 2 so the links are
      // always displayed.
      $data['tabs'][1]['count'] = isset($data['tabs'][1]['count']) ? $data['tabs'][1]['count'] + 1 : 2;
      $data['tabs'][1]['output'][] = array(
        '#theme' => 'menu_local_task',
        '#link' => array(
          'title' => $language_list[$language]->name,
          'href' => $href,
          'localized_options' => array(
            'attributes' => array(
              'class' => array(
                'language-link',
              ),
              'lang' => $language,
            ),
          ),
        ),
        '#active' => $selected_language == $language,
      );
    }
  }
}

/**
 * Alter local tasks for menu link edit form.
 *
 * @see i18n_menu_hierarchy_menu_local_tasks_alter().
 */
function i18n_menu_hierarchy_menu_local_tasks_alter_menu_edit_item(&$data, $router_item, $root_path) {
  if (empty($router_item['page_arguments'][2]) && isset($_GET['translation'])) {
    $item = menu_link_load(check_plain($_GET['translation']));
  }
  else {
    $item = $router_item['page_arguments'][2];
  }
  if ($item['i18n_tsid']) {

    // Already part of a set, grab that set.
    $translation_set = i18n_translation_set_load($item['i18n_tsid']);
    $translations = $translation_set
      ->get_translations();
  }
  else {

    // We have no translation source mlid, this could be a new set, emulate that.
    $translations = array(
      $item['language'] => $item,
    );
  }
  foreach (language_hierarchy_language_list() as $langcode => $language) {
    if (isset($translations[$langcode])) {
      $translation_item = menu_link_load($translations[$langcode]['mlid']);
      $data['tabs'][1]['count'] = isset($data['tabs'][1]['count']) ? $data['tabs'][1]['count'] + 1 : 1;
      $data['tabs'][1]['output'][] = array(
        '#theme' => 'menu_local_task',
        '#link' => array(
          'title' => $language->name,
          'href' => 'admin/structure/menu/item/' . $translation_item['mlid'] . '/edit',
          'localized_options' => array(
            'attributes' => array(
              'class' => array(
                'language-link',
              ),
              'lang' => $langcode,
            ),
          ),
        ),
        '#active' => arg(4) == $translation_item['mlid'],
      );
    }
  }
}

/**
 * Implements hook_block_view().
 */
function i18n_menu_hierarchy_block_view_alter(&$data, $block) {
  if (($block->module == 'menu' || $block->module == 'system') && i18n_menu_mode($block->delta, I18N_MODE_MULTIPLE)) {
    $menus = menu_get_menus();
    if (isset($menus[$block->delta])) {
      $localized_links = 0;
      foreach ($data['content'] as $key => $menu_link) {
        if (is_int($key) && $menu_link['#original_link']['language'] != LANGUAGE_NONE) {
          $localized_links++;
        }
      }
      if ($localized_links == 0) {
        $ancestors = language_hierarchy_get_ancestors($GLOBALS['language']->language);
        foreach ($ancestors as $langcode => $ancestor) {

          // Temporary change language so i18n_menu could load parent menu links.
          $current_language = $GLOBALS['language']->language;
          $GLOBALS['language']->language = $langcode;
          $menu_links = i18n_menu_translated_tree($block->delta);
          $GLOBALS['language']->language = $current_language;
          if ($menu_links) {
            foreach ($menu_links as $mlid => $menu_link) {
              $data['content'][$mlid] = $menu_link;
            }
            break;
          }
        }
      }
    }
  }
}

/**
 * Implements hook_form_FORM_ID_alter().
 *
 * Overhaul the menu_overview_form to improve menu authoring experience.
 */
function i18n_menu_hierarchy_form_menu_overview_form_alter(&$form, &$form_state, $form_id) {
  if ($form['#menu']['i18n_mode'] != I18N_MODE_MULTIPLE) {
    return;
  }

  // Get selected language by last part in URL path.
  $langcode = arg(6);
  if (!empty($langcode)) {
    $languages = language_hierarchy_language_list();
    if (isset($languages[$langcode])) {
      $language = $languages[$langcode];
    }
  }
  if (empty($language)) {
    $language = $GLOBALS['language'];
  }
  $menu_links_count = 0;

  // Hide menu links in different language than selected one.
  foreach (element_children($form) as $mlid) {
    $link =& $form[$mlid];
    if (isset($link['#item'])) {
      $element_langcode = $link['#item']['language'];
      if ($element_langcode != LANGUAGE_NONE && $element_langcode != $language->language) {
        unset($form[$mlid]);
        continue;
      }
      $menu_links_count++;

      // Add language prefix to links.
      $new_url = l($link['#item']['title'], $link['#item']['href'], array(
        'language' => $language,
      ));
      if ($element_langcode == LANGUAGE_NONE) {
        $new_url .= ' (' . t('all languages') . ')';
      }
      $link['title']['#markup'] = $new_url;
    }
  }
  if ($menu_links_count == 0) {
    $form['actions']['#access'] = FALSE;
    $form['#empty_text'] = t('There are no menu links yet. <a href="@link">Add link</a>.', array(
      '@link' => url('admin/structure/menu/manage/' . $form['#menu']['menu_name'] . '/add/' . $language->language),
    ));
  }

  // Add language name to title.
  drupal_set_title(drupal_get_title() . ' [' . $language->name . ']', PASS_THROUGH);
  language_hierarchy_attach_language_selector($form);
}

/**
 * Implements hook_form_FORM_ID_alter().
 *
 * Improve menu_edit_item form for better authoring experience.
 */
function i18n_menu_hierarchy_form_menu_edit_item_alter(&$form, &$form_state, $form_id) {
  if (!i18n_menu_mode($form['original_item']['#value']['menu_name'], I18N_MODE_MULTIPLE)) {
    return;
  }
  $is_new = empty($form['mlid']['#value']);
  $language_list = language_hierarchy_language_list();
  if ($is_new) {
    $selected_language = arg(6) && isset($language_list[arg(6)]) ? arg(6) : $GLOBALS['language']->language;
    $langtext = $language_list[$selected_language]->name;
    if ($form['i18n']['language']['#default_value'] == LANGUAGE_NONE) {
      $form['i18n']['language']['#default_value'] = $selected_language;
    }
  }
  else {
    $item_language = $form['original_item']['#value']['language'];
    if ($item_language == LANGUAGE_NONE) {
      $langtext = t('Language neutral');
    }
    else {
      $langtext = $language_list[$item_language]->name;
    }
  }

  // Add language name to title.
  drupal_set_title(drupal_get_title() . ' [' . $langtext . ']', PASS_THROUGH);
  language_hierarchy_attach_language_selector($form);
}

/**
 * Implements hook_i18n_translation_set_info_alter()
 */
function i18n_menu_hierarchy_i18n_translation_set_info_alter(&$info) {
  $info['menu_link']['page callback'] = 'i18n_menu_hierarchy_item_translation_page';
}

/**
 * Implements hook_form_FORM_ID_alter().
 */
function i18n_menu_hierarchy_form_i18n_string_translate_page_overview_form_alter(&$form, $form_state) {
  $languages = language_hierarchy_language_list();
  foreach ($languages as $langcode => $language) {
    $form['languages']['#rows'][$langcode]['language'] .= theme('indentation', array(
      'size' => $language->depth,
    ));
  }
}

/**
 * Callback for menu item translation tab.
 */
function i18n_menu_hierarchy_item_translation_page($type, $item) {
  module_load_include('admin.inc', 'i18n_menu');

  // If the item has a language code, we can only support translation sets.
  $translation_set = !empty($item['i18n_tsid']) ? i18n_translation_set_load($item['i18n_tsid']) : NULL;
  $overview = i18n_menu_hierarchy_item_overview($item, $translation_set);
  $translation_form = drupal_get_form('i18n_menu_translation_form', $translation_set, $item);
  $build = $overview + $translation_form;

  // Call functions implementing hook_i18n_menu_hierarchy_item_translation_page_alter().
  drupal_alter('i18n_menu_hierarchy_item_translation_page', $build, $item);
  return $build;
}

/**
 * Callback for menu translation tab overview.
 */
function i18n_menu_hierarchy_item_overview($item, $translation_set = NULL) {
  if ($item['i18n_tsid']) {

    // Already part of a set, grab that set.
    $translation_set = i18n_translation_set_load($item['i18n_tsid']);
    $translations = $translation_set
      ->get_translations();
  }
  else {

    // We have no translation source mlid, this could be a new set, emulate that.
    $translations = array(
      $item['language'] => $item,
    );
  }
  $header = array(
    t('Language'),
    t('Title'),
    t('Operations'),
  );
  $rows = array();
  foreach (language_hierarchy_language_list() as $langcode => $language) {
    $options = array();
    if (isset($translations[$langcode])) {

      // Existing translation in the translation set: display status.
      $translation_item = menu_link_load($translations[$langcode]['mlid']);
      $title = l($translation_item['link_title'], $translation_item['link_path'], array(
        'language' => $language,
      ));
      $path = 'admin/structure/menu/item/' . $translation_item['mlid'] . '/edit';
      $options[] = l(t('edit'), $path);
      if ($translation_item['mlid'] == $item['mlid']) {
        $language->name = t('<strong>@language_name</strong> (source)', array(
          '@language_name' => $language->name,
        ));
      }
    }
    else {

      // No such translation in the set yet: help user to create it.
      $title = t('n/a');
      $url_options = array(
        'query' => array(
          'translation' => $item['mlid'],
          'target' => $langcode,
          'destination' => "admin/structure/menu/manage/{$item['menu_name']}/list/{$langcode}",
        ),
      );
      $options[] = l(t('add translation'), "admin/structure/menu/manage/{$item['menu_name']}/add", $url_options);
    }
    $rows[$langcode] = array(
      'language' => theme('indentation', array(
        'size' => $language->depth,
      )) . $language->name,
      'title' => $title,
      'operations' => implode(' | ', $options),
    );
  }
  drupal_set_title(t('Translations of menu item %title', array(
    '%title' => $item['link_title'],
  )), PASS_THROUGH);
  $build['translation_overview'] = array(
    '#theme' => 'table',
    '#header' => $header,
    '#rows' => $rows,
  );
  return $build;
}