_set_menus_language(); } $this->get_current_menu(); if(isset( $_POST['action']) && $_POST['action'] == 'menu-get-metabox'){ $parts = parse_url($_SERVER['HTTP_REFERER']); @parse_str($parts['query'], $query); if(isset($query['lang'])){ $sitepress->switch_lang($query['lang']); } } if(!empty($this->current_menu['language'])){ $this->current_lang = $this->current_menu['language']; //if($this->current_lang != $sitepress->get_default_language() && !isset($_GET['lang'])){ // wp_redirect(admin_url('nav-menus.php').'?lang='.$this->current_lang); //} }elseif(isset($_REQUEST['lang'])){ $this->current_lang = $_REQUEST['lang']; }elseif($lang = $sitepress->get_language_cookie()){ $this->current_lang = $lang; }else{ $this->current_lang = $sitepress->get_default_language(); } if(isset($_POST['icl_wp_nav_menu_ajax'])){ $this->ajax($_POST); } // for theme locations that are not translated into the curent language // reflect status in the theme location navigation switcher add_action('admin_footer', array($this, '_set_custom_status_in_theme_location_switcher')); // filter menu by language when adjust ids is off // not on ajax calls if(!$sitepress_settings['auto_adjust_ids'] && !defined('DOING_AJAX')){ add_filter('get_term', array($sitepress, 'get_term_adjust_id')); } // Setup Menus Sync add_action('admin_menu', array($this, 'admin_menu_setup')); if(isset($_GET['page']) && $_GET['page'] == ICL_PLUGIN_FOLDER . '/menu/menus-sync.php'){ global $icl_menus_sync; include_once ICL_PLUGIN_PATH . '/inc/wp-nav-menus/menus-sync.php'; $icl_menus_sync = new ICLMenusSync; } } // Menus sync submenu function admin_menu_setup(){ $top_page = apply_filters('icl_menu_main_page', ICL_PLUGIN_FOLDER.'/menu/languages.php'); add_submenu_page( $top_page, __( 'WP Menus Sync', 'sitepress' ), __( 'WP Menus Sync', 'sitepress' ), 'manage_options', ICL_PLUGIN_FOLDER . '/menu/menus-sync.php' ); } /** * associates menus without language information with default language * */ function _set_menus_language(){ global $wpdb, $sitepress; $translated_menus = $wpdb->get_col(" SELECT element_id FROM {$wpdb->prefix}icl_translations WHERE element_type='tax_nav_menu' "); $translated_menus[] = 0; //dummy $untranslated_menus = $wpdb->get_col(" SELECT term_taxonomy_id FROM {$wpdb->term_taxonomy} WHERE taxonomy='nav_menu' AND term_taxonomy_id NOT IN(".join(",",$translated_menus).") "); if(!empty($untranslated_menus)){ foreach($untranslated_menus as $item){ $sitepress->set_element_language_details($item, 'tax_nav_menu', null, $sitepress->get_default_language()); } } $translated_menu_items = $wpdb->get_col(" SELECT element_id FROM {$wpdb->prefix}icl_translations WHERE element_type='post_nav_menu_item' AND element_id IS NOT NULL "); $translated_menu_items[] = 0; //dummy $untranslated_menu_items = $wpdb->get_col(" SELECT ID FROM {$wpdb->posts} WHERE post_type='nav_menu_item' AND ID NOT IN(".join(",", $translated_menu_items).") "); if(!empty($untranslated_menu_items)){ foreach($untranslated_menu_items as $item){ $sitepress->set_element_language_details($item, 'post_nav_menu_item', null, $sitepress->get_default_language()); } } } function ajax($data){ if($data['icl_wp_nav_menu_ajax'] == 'translation_of'){ $trid = isset($data['trid']) ? $data['trid'] : false; $this->_render_translation_of($data['lang'], $trid); } exit; } function _get_menu_language($menu_id){ global $sitepress, $wpdb; $menu_tt_id = $wpdb->get_var($wpdb->prepare("SELECT term_taxonomy_id FROM {$wpdb->term_taxonomy} WHERE term_id=%d AND taxonomy='nav_menu'",$menu_id)); $lang = $sitepress->get_element_language_details($menu_tt_id, 'tax_nav_menu'); return $lang; } /** * gets first menu in a specific language * used to override nav_menu_recently_edited when a different language is selected * @param $lang * @return int */ function _get_first_menu($lang){ global $wpdb; $menu_tt_id = $wpdb->get_var("SELECT MIN(element_id) FROM {$wpdb->prefix}icl_translations WHERE element_type='tax_nav_menu' AND language_code='".$wpdb->escape($lang)."'"); $menu_id = $wpdb->get_var($wpdb->prepare("SELECT term_id FROM {$wpdb->term_taxonomy} WHERE term_taxonomy_id=%d",$menu_tt_id)); return (int) $menu_id; } function get_current_menu(){ global $sitepress; $nav_menu_recently_edited = get_user_option( 'nav_menu_recently_edited' ); $nav_menu_recently_edited_lang = $this->_get_menu_language($nav_menu_recently_edited); if( !isset( $_REQUEST['menu'] ) && isset($nav_menu_recently_edited_lang->language_code) && $nav_menu_recently_edited_lang->language_code != $sitepress->get_current_language()){ // if no menu is specified and the language is set override nav_menu_recently_edited $nav_menu_selected_id = $this->_get_first_menu($sitepress->get_current_language()); if($nav_menu_selected_id){ update_user_option(get_current_user_id(), 'nav_menu_recently_edited', $nav_menu_selected_id); }else{ $_REQUEST['menu'] = 0; } }elseif( !isset( $_REQUEST['menu'] ) && !isset($_GET['lang']) && (empty($nav_menu_recently_edited_lang->language_code) || $nav_menu_recently_edited_lang->language_code != $sitepress->get_admin_language_cookie()) && (empty($_POST['action']) || $_POST['action']!='update')){ // if no menu is specified, no language is set, override nav_menu_recently_edited if its language is different than default $nav_menu_selected_id = $this->_get_first_menu($sitepress->get_admin_language_cookie()); update_user_option(get_current_user_id(), 'nav_menu_recently_edited', $nav_menu_selected_id); }elseif(isset( $_REQUEST['menu'] )){ $nav_menu_selected_id = $_REQUEST['menu']; }else{ $nav_menu_selected_id = $nav_menu_recently_edited; } $this->current_menu['id'] = $nav_menu_selected_id; if($this->current_menu['id']){ $this->_load_menu($this->current_menu['id']); }else{ $this->current_menu['trid'] = isset($_GET['trid']) ? intval($_GET['trid']) : null; if(isset($_POST['icl_nav_menu_language'])){ $this->current_menu['language'] = $_POST['icl_nav_menu_language']; }elseif(isset($_GET['lang'])){ $this->current_menu['language'] = $_GET['lang']; }else{ $this->current_menu['language'] = $sitepress->get_admin_language_cookie(); } $this->current_menu['translations'] = array(); } } function _load_menu($menu_id){ global $sitepress, $wpdb; $menu_tt_id = $wpdb->get_var($wpdb->prepare("SELECT term_taxonomy_id FROM {$wpdb->term_taxonomy} WHERE term_id=%d AND taxonomy='nav_menu'",$this->current_menu['id'])); $this->current_menu['trid'] = $sitepress->get_element_trid($menu_tt_id, 'tax_nav_menu'); if($this->current_menu['trid']){ $this->current_menu['translations'] = $sitepress->get_element_translations($this->current_menu['trid'], 'tax_nav_menu'); }else{ $this->current_menu['translations'] = array(); } foreach($this->current_menu['translations'] as $tr){ if($menu_tt_id == $tr->element_id){ $this->current_menu['language'] = $tr->language_code; } } } function wp_update_nav_menu($menu_id, $menu_data = null){ global $sitepress, $wpdb; if($menu_data){ if(isset($_POST['icl_translation_of']) && $_POST['icl_translation_of']){ $trid = $sitepress->get_element_trid($_POST['icl_translation_of'], 'tax_nav_menu'); }else{ $trid = isset($_POST['icl_nav_menu_trid']) ? intval($_POST['icl_nav_menu_trid']) : null; } $language_code = isset($_POST['icl_nav_menu_language']) ? $_POST['icl_nav_menu_language'] : $sitepress->get_default_language(); $menu_id_tt = $wpdb->get_var($wpdb->prepare("SELECT term_taxonomy_id FROM {$wpdb->term_taxonomy} WHERE term_id=%d AND taxonomy='nav_menu'",$menu_id)); $sitepress->set_element_language_details($menu_id_tt, 'tax_nav_menu', $trid, $language_code); } $this->current_menu['id'] = $menu_id; $this->_load_menu($this->current_menu['id']); } function wp_delete_nav_menu($id){ global $wpdb; $menu_id_tt = $wpdb->get_var($wpdb->prepare("SELECT term_taxonomy_id FROM {$wpdb->term_taxonomy} WHERE term_id=%d AND taxonomy='nav_menu'",$id)); $wpdb->query("DELETE FROM {$wpdb->prefix}icl_translations WHERE element_id='{$menu_id_tt}' AND element_type='tax_nav_menu' LIMIT 1"); } function wp_update_nav_menu_item($menu_id, $menu_item_db_id, $args){ // TBD // TBD global $sitepress; // deal with the case of auto-added pages /* if(isset($_POST['icl_post_language'])){ $menu_language = $this->_get_menu_language($menu_id); if($menu_language != $_POST['icl_post_language']){ _wp_delete_post_menu_item($menu_id); return; } } */ $trid = null; $language_code = $this->current_lang; $sitepress->set_element_language_details($menu_item_db_id, 'post_nav_menu_item', $trid, $language_code); } function wp_delete_nav_menu_item($menu_item_id){ global $wpdb; $post = get_post($menu_item_id); if(!empty($post->post_type) && $post->post_type == 'nav_menu_item'){ $wpdb->query("DELETE FROM {$wpdb->prefix}icl_translations WHERE element_id='{$menu_item_id}' AND element_type='post_nav_menu_item' LIMIT 1"); } } function nav_menu_language_controls(){ global $sitepress, $wpdb; if($this->current_menu['language'] != $sitepress->get_default_language()){ $menus_wout_translation = $this->get_menus_without_translation($this->current_menu['language']); } if(isset($this->current_menu['translations'][$sitepress->get_default_language()])){ $menus_wout_translation['0'] = (object)array( 'element_id'=>$this->current_menu['translations'][$sitepress->get_default_language()]->element_id, 'trid' =>'0', 'name' =>$this->current_menu['translations'][$sitepress->get_default_language()]->name ); } $langsel = '
'; // show translations links if this is not a new element if($this->current_menu['id']){ $langsel .= '
'; $langsel .= __('Translations:', 'sitepress'); foreach($sitepress->get_active_languages() as $lang){ if($lang['code'] == $this->current_menu['language']) continue; if(isset($this->current_menu['translations'][$lang['code']])){ $lang_suff = '&lang=' . $lang['code']; $menu_id = $wpdb->get_var($wpdb->prepare("SELECT term_id FROM {$wpdb->term_taxonomy} WHERE term_taxonomy_id=%d",$this->current_menu['translations'][$lang['code']]->element_id)); $tr_link = ''. $lang['display_name'] . ' '. esc_attr(__('edit', 'sitepress')).
                        ''; }else{ $tr_link = ''. $lang['display_name'] . ' '. esc_attr(__('add', 'sitepress')).
                        ''; } $trs[] = $tr_link ; } $langsel .= ' ' . join (', ', $trs); $langsel .= '

'; $langsel .= '
'; $langsel .= '
' . __('Synchronize menus between languages.', 'sitepress') . '
'; $langsel .= '
'; } // show languages dropdown $langsel .= ''; // show 'translation of' if this element is not in the default language and there are untranslated elements $langsel .= ''; if($this->current_menu['language'] != $sitepress->get_default_language() && !empty($menus_wout_translation)){ $langsel .= ''; } $langsel .= ''; // add trid to form if($this->current_menu['trid']){ $langsel .= ''; } $langsel .= ''; ?> get_results(" SELECT ts.element_id, ts.trid, t.name FROM {$wpdb->prefix}icl_translations ts JOIN {$wpdb->term_taxonomy} tx ON ts.element_id = tx.term_taxonomy_id JOIN {$wpdb->terms} t ON tx.term_id = t.term_id WHERE ts.element_type='tax_nav_menu' AND ts.language_code='{$sitepress->get_default_language()}' AND tx.taxonomy = 'nav_menu' "); $menus = array(); foreach($res as $row){ if(!$wpdb->get_var("SELECT translation_id FROM {$wpdb->prefix}icl_translations WHERE trid='{$row->trid}' AND language_code='{$lang}'")){ $menus[$row->trid] = $row; } } return $menus; } function _render_translation_of($lang, $trid = false){ global $sitepress; $out = ''; if($sitepress->get_default_language() != $lang){ $menus = $this->get_menus_without_translation($lang); $out .= ''; } echo $out; } function get_menus_by_language(){ global $wpdb, $sitepress; $res = $wpdb->get_results(" SELECT lt.name AS language_name, l.code AS lang, COUNT(ts.translation_id) AS c FROM {$wpdb->prefix}icl_languages l JOIN {$wpdb->prefix}icl_languages_translations lt ON lt.language_code = l.code JOIN {$wpdb->prefix}icl_translations ts ON l.code = ts.language_code WHERE lt.display_language_code='".$sitepress->get_admin_language()."' AND l.active = 1 AND ts.element_type = 'tax_nav_menu' GROUP BY ts.language_code ORDER BY major DESC, english_name ASC "); foreach($res as $row){ $langs[$row->lang] = $row; } return $langs; } function languages_menu($echo = true){ global $sitepress; $langs = $this->get_menus_by_language(); // include empty languages foreach($sitepress->get_active_languages() as $lang){ if(!isset($langs[$lang['code']])){ $langs[$lang['code']] = new stdClass(); $langs[$lang['code']]->language_name = $lang['display_name']; $langs[$lang['code']]->lang = $lang['code']; $langs[$lang['code']]->c = 0; } } $url = admin_url('nav-menus.php'); foreach($langs as $l){ $class = $l->lang == $this->current_lang ? ' class="current"' : ''; $urlsuff = '?lang=' . $l->lang; $ls[] = ''.esc_html($l->language_name).' ('.$l->c.')'; } $ls_string = '
'; $ls_string .= join(' | ', $ls); $ls_string .= '
'; if($echo){ echo $ls_string; }else{ return $ls_string; } } function get_terms_filter($terms, $taxonomies, $args){ global $wpdb, $sitepress, $pagenow; // deal with the case of not translated taxonomies // we'll assume that it's called as just a single item if(!$sitepress->is_translated_taxonomy($taxonomies[0]) && 'nav_menu' != $taxonomies[0]){ return $terms; } // special case for determining list of menus for updating auto-add option if($taxonomies[0] == 'nav_menu' && $args['fields'] == 'ids' && $_POST['action'] == 'update' && $pagenow=='nav-menus.php'){ return $terms; } if(!empty($terms)){ foreach($taxonomies as $t){ $txs[] = 'tax_' . $t; } $el_types = "'".join(',',$txs)."'"; // get all term_taxonomy_id's $tt = array(); foreach($terms as $t){ if(is_object($t)){ $tt[] = $t->term_taxonomy_id; }else{ if(is_numeric($t)){ $tt[] = $t; } } } // filter the ones in the current language if(!empty($tt)){ $ftt = $wpdb->get_col("SELECT element_id FROM {$wpdb->prefix}icl_translations WHERE element_type IN ({$el_types}) AND element_id IN (".join(',',$tt).") AND language_code='{$this->current_lang}'"); } foreach($terms as $k=>$v){ if(isset($v->term_taxonomy_id) && !in_array($v->term_taxonomy_id, $ftt)){ unset($terms[$k]); } } } return $terms; } // filter posts by language function parse_query($q){ global $sitepress; // not filtering nav_menu_item if($q->query_vars['post_type'] == 'nav_menu_item'){ return $q; } // also - not filtering custom posts that are not translated if($sitepress->is_translated_post_type($q->query_vars['post_type'])){ $q->query_vars['suppress_filters'] = 0; } return $q; } function theme_mod_nav_menu_locations($val){ global $sitepress; if($sitepress->get_default_language() != $this->current_lang){ if(!empty($val)){ foreach($val as $k=>$v){ $val[$k] = icl_object_id($val[$k], 'nav_menu', true, $this->current_lang); } } } return $val; } function pre_update_theme_mods_theme($val){ global $sitepress; if(isset($val['nav_menu_locations'])){ foreach((array)$val['nav_menu_locations'] as $k=>$v){ if(!$v && $this->current_lang != $sitepress->get_default_language()){ $tl = get_theme_mod('nav_menu_locations'); $val['nav_menu_locations'][$k] = $tl[$k]; }else{ $val['nav_menu_locations'][$k] = icl_object_id($val['nav_menu_locations'][$k], 'nav_menu',true, $sitepress->get_default_language()); } } } return $val; } function option_nav_menu_options($val){ global $wpdb; // special case of getting menus with auto-add only in a specific language $db = debug_backtrace(); if(isset($db[4]) && $db[4]['function'] == '_wp_auto_add_pages_to_menu' && !empty($val['auto_add'])){ $post_lang = $_POST['icl_post_language']; $val['auto_add'] = $wpdb->get_col(" SELECT element_id FROM {$wpdb->prefix}icl_translations WHERE element_type='tax_nav_menu' AND element_id IN (".join(',',$val['auto_add']).") AND language_code = '{$post_lang}'"); } return $val; } function wp_nav_menu_args_filter($args){ global $sitepress; if ( ! $args['menu'] ){ $locations = get_nav_menu_locations(); if(isset( $args['theme_location'] ) && isset($locations[$args['theme_location']])){ $args['menu'] = icl_object_id($locations[$args['theme_location']], 'nav_menu'); } }; if ( ! $args['menu'] ){ remove_filter('theme_mod_nav_menu_locations', array($this, 'theme_mod_nav_menu_locations')); $locations = get_nav_menu_locations(); if(isset( $args['theme_location'] ) && isset($locations[$args['theme_location']])){ $args['menu'] = icl_object_id($locations[$args['theme_location']], 'nav_menu'); } add_filter('theme_mod_nav_menu_locations', array($this, 'theme_mod_nav_menu_locations')); } if ( $args['menu'] ){ $db = debug_backtrace(); if($db[4]['function']=='widget'){ if(is_integer($args['menu'])){ $args['menu'] = wp_get_nav_menu_object( icl_object_id($args['menu'], 'nav_menu') ); }elseif(!empty($args['menu']->term_id)){ $args['menu'] = wp_get_nav_menu_object( icl_object_id($args['menu']->term_id, 'nav_menu') ); } } } return $args; } function wp_nav_menu_items_filter($items){ $items = preg_replace( '|