menu_item_sync = new WPML_Menu_Item_Sync( $this->sitepress, $this->wpdb, $this->post_translations, $this->term_translations ); $this->init_hooks(); } function init_hooks() { add_action( 'init', array( $this, 'init' ), 20 ); if ( isset( $_GET['updated'] ) ) { add_action( 'admin_notices', array( $this, 'admin_notices' ) ); } } function init( $previous_menu = false ) { $this->sitepress->switch_lang( $this->sitepress->get_default_language() ); $action = filter_input( INPUT_POST, 'action' ); $nonce = (string) filter_input( INPUT_POST, '_icl_nonce_menu_sync' ); if ( $action && ! wp_verify_nonce( $nonce, '_icl_nonce_menu_sync' ) ) { wp_send_json_error( 'Invalid nonce' ); } $this->menu_item_sync->cleanup_broken_page_items(); if (!session_id()) { session_start(); } if ( $action === 'icl_msync_preview' ) { $this->is_preview = true; $this->sync_data = isset( $_POST['sync'] ) ? array_map( 'stripslashes_deep', $_POST['sync'] ) : false; $previous_menu = isset( $_SESSION[ 'wpml_menu_sync_menu' ] ) ? $_SESSION[ 'wpml_menu_sync_menu' ] : null; } if ( $previous_menu ) { $this->menus = $previous_menu; } else { $this->get_menus_tree(); $_SESSION[ 'wpml_menu_sync_menu' ] = $this->menus; } $this->sitepress->switch_lang(); } function get_menu_names() { $menu_names = array(); global $sitepress, $wpdb; $menus = $wpdb->get_results( $wpdb->prepare( " SELECT tm.term_id, tm.name FROM {$wpdb->terms} tm JOIN {$wpdb->term_taxonomy} tx ON tx.term_id = tm.term_id JOIN {$wpdb->prefix}icl_translations tr ON tr.element_id = tx.term_taxonomy_id AND tr.element_type='tax_nav_menu' WHERE tr.language_code=%s ", $sitepress->get_default_language() ) ); if ( $menus ) { foreach ( $menus as $menu ) { $menu_names[] = $menu->name; } } return $menu_names; } function get_menus_tree() { global $sitepress, $wpdb; $menus = $wpdb->get_results( $wpdb->prepare( " SELECT tm.term_id, tm.name FROM {$wpdb->terms} tm JOIN {$wpdb->term_taxonomy} tx ON tx.term_id = tm.term_id JOIN {$wpdb->prefix}icl_translations tr ON tr.element_id = tx.term_taxonomy_id AND tr.element_type='tax_nav_menu' WHERE tr.language_code=%s ", $sitepress->get_default_language() ) ); if ( $menus ) { foreach ( $menus as $menu ) { $this->menus[ $menu->term_id ] = array( 'name' => $menu->name, 'items' => $this->get_menu_items( $menu->term_id, true ), 'translations' => $this->get_menu_translations( $menu->term_id ) ); } $this->add_ghost_entries(); $this->set_new_menu_order(); } } private function get_menu_options( $menu_id ) { $menu_options = get_option( 'nav_menu_options' ); $options = array( 'auto_add' => isset( $menu_options['auto_add'] ) && in_array( $menu_id, $menu_options['auto_add'] ) ); return $options; } function add_ghost_entries() { if ( is_array( $this->menus ) ) { foreach ( $this->menus as $menu_id => $menu ) { if ( ! is_array( $menu['translations'] ) ) { continue; } foreach ( $menu['translations'] as $language => $tmenu ) { if ( ! empty( $tmenu ) ) { foreach ( $tmenu['items'] as $titem ) { // has a place in the default menu? $exists = false; foreach ( $this->menus[ $menu_id ]['items'] as $item ) { if ( $item['translations'][ $language ]['ID'] == $titem['ID'] ) { $exists = true; } } if ( ! $exists ) { $this->menus[ $menu_id ]['translations'][ $language ]['deleted_items'][] = array( 'ID' => $titem['ID'], 'title' => $titem['title'], 'menu_order' => $titem['menu_order'] ); } } } } } } } function set_new_menu_order() { if ( is_array( $this->menus ) ) { foreach ( $this->menus as $menu_id => $menu ) { $menu_index_by_lang = array(); foreach ( $menu[ 'items' ] as $item_id => $item ) { foreach ( $item[ 'translations' ] as $language => $item_translation ) { if ( $item_translation[ 'ID' ] ) { $new_menu_order = empty( $menu_index_by_lang[ $language ] ) ? 1 : $menu_index_by_lang[ $language ] + 1; $menu_index_by_lang[ $language ] = $new_menu_order; $this->menus[ $menu_id ][ 'items' ][ $item_id ][ 'translations' ][ $language ][ 'menu_order_new' ] = $new_menu_order; } } } } } } function do_sync( array $data ) { $this->menus = isset( $this->menus ) ? $this->menus : array(); $this->menus = empty( $data['menu_translation'] ) ? $this->menus : $this->menu_item_sync->sync_menu_translations( $data['menu_translation'], $this->menus ); if ( ! empty( $data['options_changed'] ) ) { $this->menu_item_sync->sync_menu_options( $data['options_changed'] ); } if ( ! empty( $data['del'] ) ) { $this->menu_item_sync->sync_deleted_menus( $data['del'] ); } $this->menus = empty( $data['mov'] ) ? $this->menus : $this->menu_item_sync->sync_moved_items( $data['mov'], $this->menus ); $this->menus = empty( $data['add'] ) ? $this->menus : $this->menu_item_sync->sync_added_items( $data['add'], $this->menus ); if ( ! empty( $data['label_changed'] ) ) { $this->menu_item_sync->sync_caption( $data['label_changed'] ); } if ( ! empty( $data['url_changed'] ) ) { $this->menu_item_sync->sync_urls( $data['url_changed'] ); } if ( ! empty( $data['label_missing'] ) ) { $this->menu_item_sync->sync_missing_captions( $data['label_missing'] ); } if ( ! empty( $data['url_missing'] ) ) { $this->menu_item_sync->sync_urls_to_add( $data['url_missing'] ); } $this->menus = isset( $this->menus ) ? $this->menu_item_sync->sync_menu_order( $this->menus ) : $this->menus; $this->menu_item_sync->cleanup_broken_page_items(); return $this->menus; } function render_items_tree_default( $menu_id, $parent = 0, $depth = 0 ) { global $sitepress; $active_language_codes = array_keys( $sitepress->get_active_languages() ); $need_sync = 0; $default_language = $sitepress->get_default_language(); foreach ( $this->menus[ $menu_id ][ 'items' ] as $item ) { // deleted items #2 (menu order beyond) static $d2_items = array(); $deleted_items = array(); if ( isset( $this->menus[ $menu_id ][ 'translation' ] ) && is_array( $this->menus[ $menu_id ][ 'translation' ] ) ) { foreach ( $this->menus[ $menu_id ][ 'translations' ] as $language => $tmenu ) { if ( ! isset( $d2_items[ $language ] ) ) { $d2_items[ $language ] = array(); } if ( ! empty( $this->menus[ $menu_id ][ 'translations' ][ $language ][ 'deleted_items' ] ) ) { foreach ( $this->menus[ $menu_id ][ 'translations' ][ $language ][ 'deleted_items' ] as $deleted_item ) { if ( ! in_array( $deleted_item[ 'ID' ], $d2_items[ $language ] ) && $deleted_item[ 'menu_order' ] > count( $this->menus[ $menu_id ][ 'items' ] ) ) { $deleted_items[ $language ][ ] = $deleted_item; $d2_items[ $language ][ ] = $deleted_item[ 'ID' ]; } } } } } if ( $deleted_items ) { ?>
' . esc_html__( 'Menu(s) syncing complete.', 'sitepress' ) . '
';
esc_html_e( "Your menu includes custom items, which you need to translate using WPML's String Translation.", 'sitepress' );
echo '
';
esc_html_e( '1. Translate these strings: ', 'sitepress' );
$i = 0;
foreach ( $menu_links_data['items'] as $menu_name => $menu_url ) {
if ( $i > 0 ) {
echo ', ';
}
echo '' . esc_html( $menu_name ) . '' . PHP_EOL;
$i ++;
}
echo '
';
esc_html_e( "2. When you're done translating, return here and run the menu synchronization again. This will use the strings that you translated to update the menus.", 'sitepress' );
echo '