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() {
if ( is_admin() ) {
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' ) );
}
if ( $this->must_filter_menus() ) {
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' ) );
}
/**
* @return bool
*/
private function must_filter_menus() {
global $pagenow;
return 'nav-menus.php' === $pagenow
|| 'widgets.php' === $pagenow
|| filter_input( INPUT_POST, 'action' ) === 'save-widget';
}
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', array( 'jquery' ), 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;
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() );
}
/**
* @param string $menu_id
*/
function admin_menu_setup( $menu_id ) {
if ( 'WPML' !== $menu_id ) {
return;
}
$menu = array();
$menu['order'] = 700;
$menu['page_title'] = __( 'WP Menus Sync', 'sitepress' );
$menu['menu_title'] = __( 'WP Menus Sync', 'sitepress' );
$menu['capability'] = 'wpml_manage_wp_menus_sync';
$menu['menu_slug'] = WPML_PLUGIN_FOLDER . '/menu/menu-sync/menus-sync.php';
do_action( 'wpml_admin_menu_register_item', $menu );
}
/**
*
* 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;
}
private function get_action_icon( $css_class, $label ) {
return '';
}
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 .= '