sitepress = $sitepress;
$this->wpdb = $wpdb;
$this->post_translations = $post_translations;
$this->term_translations = $term_translations;
$this->nav_menu_actions = new WPML_Nav_Menu_Actions( $sitepress,
$wpdb,
$post_translations,
$term_translations );
}
public function init_hooks() {
global $pagenow;
if ( is_admin() ) {
// filter for nav_menu_options
add_filter( 'option_nav_menu_options', array( $this, 'option_nav_menu_options' ) );
add_filter( 'wp_get_nav_menus', array( $this, 'wp_get_nav_menus_filter' ) );
}
// filter menus by language - also on the widgets page
if ( 'nav-menus.php' === $pagenow
|| 'widgets.php' === $pagenow
|| ( isset( $_POST['action'] ) && 'save-widget' === $_POST['action'] )
) {
add_filter( 'get_terms', array( $this, 'get_terms_filter' ), 1, 3 );
}
add_action( 'init', array( $this, 'init' ) );
add_filter( 'wp_nav_menu_args', array( $this, 'wp_nav_menu_args_filter' ) );
add_filter( 'wp_nav_menu_items', array( $this, 'wp_nav_menu_items_filter' ) );
add_filter( 'nav_menu_meta_box_object', array( $this, '_enable_sitepress_query_filters' ) );
}
function init(){
/** @var WPML_Request $wpml_request_handler */
/** @var WPML_Language_Resolution $wpml_language_resolution */
global $sitepress, $sitepress_settings, $pagenow, $wpml_request_handler, $wpml_language_resolution;
$this->adjust_current_language_if_required();
$default_language = $sitepress->get_default_language();
// add language controls for menus no option but javascript
if($pagenow === 'nav-menus.php'){
add_action('admin_footer', array($this, 'nav_menu_language_controls'), 10);
wp_enqueue_script('wp_nav_menus', ICL_PLUGIN_URL . '/res/js/wp-nav-menus.js', ICL_SITEPRESS_VERSION, true);
wp_enqueue_style('wp_nav_menus_css', ICL_PLUGIN_URL . '/res/css/wp-nav-menus.css', array(), ICL_SITEPRESS_VERSION,'all');
// filter posts by language
add_action('parse_query', array($this, 'parse_query'));
}
if(is_admin()){
$this->_set_menus_language();
$this->get_current_menu();
}
if ( isset( $_POST[ 'action' ] )
&& $_POST[ 'action' ] === 'menu-get-metabox'
&& (bool) ( $lang = $wpml_language_resolution->get_referrer_language_code() ) !== false
) {
$sitepress->switch_lang ( $lang );
}
if ( isset( $this->current_menu[ 'language' ] )
&& isset( $this->current_menu[ 'id' ] )
&& $this->current_menu[ 'id' ]
&& $this->current_menu[ 'language' ]
&& $this->current_menu[ 'language' ] != $default_language
&& isset( $_GET[ 'menu' ] )
&& empty( $_GET[ 'lang' ] )
) {
wp_redirect(
admin_url(
sprintf(
'nav-menus.php?menu=%d&lang=%s',
$this->current_menu[ 'id' ],
$this->current_menu[ 'language' ]
)
)
);
}
$this->current_lang = $wpml_request_handler->get_requested_lang();
if(isset($_POST['icl_wp_nav_menu_ajax'])){
$this->ajax($_POST);
}
// for theme locations that are not translated into the current 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'), 1, 1);
}
$this->setup_menu_item();
if ( $this->sitepress->get_wp_api()->is_core_page( 'menu-sync/menus-sync.php' ) ) {
$this->setup_menu_synchronization();
}
add_action( 'wp_ajax_icl_msync_confirm', array( $this, 'sync_menus_via_ajax' ) );
add_action( 'wp_ajax_wpml_get_links_for_menu_strings_translation', array( $this, 'get_links_for_menu_strings_translation_ajax' ) );
}
function sync_menus_via_ajax( ) {
if ( isset( $_POST[ '_icl_nonce_menu_sync' ] ) && wp_verify_nonce( $_POST[ '_icl_nonce_menu_sync' ], '_icl_nonce_menu_sync' ) ) {
if (!session_id()) {
session_start();
}
global $icl_menus_sync,$wpdb, $wpml_post_translations, $wpml_term_translations, $sitepress;
include_once WPML_PLUGIN_PATH . '/inc/wp-nav-menus/menus-sync.php';
$icl_menus_sync = new ICLMenusSync( $sitepress, $wpdb, $wpml_post_translations, $wpml_term_translations );
$icl_menus_sync->init( isset( $_SESSION[ 'wpml_menu_sync_menu' ] ) ? $_SESSION[ 'wpml_menu_sync_menu' ] : null );
$results = $icl_menus_sync->do_sync( $_POST['sync']);
$_SESSION[ 'wpml_menu_sync_menu' ] = $results;
$_SESSION[ 'wpml_menu_sync_menu' ] = $results;
wp_send_json_success( true );
} else {
wp_send_json_error( false );
}
}
public function get_links_for_menu_strings_translation_ajax() {
global $icl_menus_sync, $wpml_post_translations, $wpml_term_translations;
include_once WPML_PLUGIN_PATH . '/inc/wp-nav-menus/menus-sync.php';
$icl_menus_sync = new ICLMenusSync( $this->sitepress, $this->wpdb, $wpml_post_translations, $wpml_term_translations );
wp_send_json_success( $icl_menus_sync->get_links_for_menu_strings_translation() );
}
// Menus sync submenu
function admin_menu_setup(){
global $sitepress;
if(!isset($sitepress) || !$sitepress->get_setting( 'setup_complete' )) return;
$top_page = apply_filters('icl_menu_main_page', WPML_PLUGIN_FOLDER.'/menu/languages.php');
add_submenu_page( $top_page,
__( 'WP Menus Sync', 'sitepress' ), __( 'WP Menus Sync', 'sitepress' ),
'wpml_manage_wp_menus_sync', WPML_PLUGIN_FOLDER . '/menu/menu-sync/menus-sync.php' );
}
/**
*
* Associates menus without language information with default language
*
*/
private function _set_menus_language() {
global $wpdb, $sitepress;
$default_language = $sitepress->get_default_language ();
$untranslated_menus = $wpdb->get_col (
"
SELECT term_taxonomy_id
FROM {$wpdb->term_taxonomy} tt
LEFT JOIN {$wpdb->prefix}icl_translations i
ON CONCAT('tax_', tt.taxonomy ) = i.element_type
AND i.element_id = tt.term_taxonomy_id
WHERE tt.taxonomy='nav_menu'
AND i.language_code IS NULL"
);
foreach ( (array) $untranslated_menus as $item ) {
$sitepress->set_element_language_details ( $item, 'tax_nav_menu', null, $default_language );
}
$untranslated_menu_items = $wpdb->get_col (
"
SELECT p.ID
FROM {$wpdb->posts} p
LEFT JOIN {$wpdb->prefix}icl_translations i
ON CONCAT('post_', p.post_type ) = i.element_type
AND i.element_id = p.ID
WHERE p.post_type = 'nav_menu_item'
AND i.language_code IS NULL"
);
if ( !empty( $untranslated_menu_items ) ) {
foreach ( $untranslated_menu_items as $item ) {
$sitepress->set_element_language_details ( $item, 'post_nav_menu_item', null, $default_language );
}
}
}
function ajax( $data ) {
if ( $data['icl_wp_nav_menu_ajax'] == 'translation_of' ) {
$trid = isset( $data['trid'] ) ? $data['trid'] : false;
echo $this->render_translation_of( $data['lang'], $trid );
}
exit;
}
function _get_menu_language($menu_id){
/** @var WPML_Term_Translation $wpml_term_translations */
global $wpml_term_translations;
return $menu_id ? $wpml_term_translations->lang_code_by_termid($menu_id) : false;
}
/**
*
* Gets first menu in a specific language
* used to override nav_menu_recently_edited when a different language is selected
*
* @param string $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='".esc_sql($lang)."'");
return $menu_tt_id
? (int)$wpdb->get_var($wpdb->prepare("SELECT term_id FROM {$wpdb->term_taxonomy} WHERE term_taxonomy_id=%d",$menu_tt_id))
: false;
}
function get_current_menu(){
global $sitepress, $wpml_request_handler;
$nav_menu_recently_edited = get_user_option ( 'nav_menu_recently_edited' );
$nav_menu_recently_edited_lang = $this->_get_menu_language ( $nav_menu_recently_edited );
$current_language = $sitepress->get_current_language ();
$admin_language_cookie = $wpml_request_handler->get_cookie_lang();
if( !isset( $_REQUEST['menu'] ) && $nav_menu_recently_edited_lang != $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( $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) || $nav_menu_recently_edited_lang != $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( $current_language );
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'] ) ? (int) $_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'] = (int) $_GET['lang'];
}else{
$this->current_menu['language'] = $admin_language_cookie;
}
$this->current_menu['translations'] = array();
}
}
/**
* @param bool|int $menu_id
*
* @return array
*/
function _load_menu( $menu_id = false ) {
$menu_id = $menu_id ? $menu_id : $this->current_menu['id'];
$menu_term_object = get_term( $menu_id, 'nav_menu' );
if ( ! empty( $menu_term_object->term_taxonomy_id ) ) {
$ttid = $menu_term_object->term_taxonomy_id;
$current_menu = array( 'id' => $menu_id );
$current_menu['trid'] = $this->term_translations->get_element_trid( $ttid );
$current_menu['translations'] = $current_menu['trid']
? $this->sitepress->get_element_translations( $current_menu['trid'], 'tax_nav_menu' ) : array();
$current_menu['language'] = $this->term_translations->lang_code_by_termid( $menu_id );
}
$this->current_menu = ! empty( $current_menu['translations'] ) ? $current_menu : null;
return $this->current_menu;
}
function nav_menu_language_controls() {
global $sitepress, $wpdb;
$this->_load_menu();
$default_language = $sitepress->get_default_language();
$current_lang = isset( $this->current_menu['language'] ) ? $this->current_menu['language'] : $sitepress->get_current_language();
$langsel = '
';
// show translations links if this is not a new element
if(isset($this->current_menu['id']) && $this->current_menu['id']){
$langsel .= '