base === 'post' && isset($_GET['post'])) { $post_id = absint($_GET['post']); } elseif (isset($GLOBALS['post']->ID)) { $post_id = absint($GLOBALS['post']->ID); } } else { $post_id = get_queried_object_id(); if (!$post_id && (is_front_page() || is_home())) { $post_id = absint(get_option('page_on_front')); } if (!$post_id && isset($GLOBALS['post']->ID)) { $post_id = absint($GLOBALS['post']->ID); } } $has_page_context = false; $page_lang_data = null; if ($post_id && (current_user_can('edit_post', $post_id) || current_user_can('manage_options'))) { $multilingual = class_exists('AITRFOEL_Multilingual_Manager') ? AITRFOEL_Multilingual_Manager::get_instance() : null; if ($multilingual && $multilingual->is_active() && $multilingual->has_languages_configured()) { $available_langs = $multilingual->get_available_languages(); if (count($available_langs) >= 2) { $has_page_context = true; $post_lang = $multilingual->get_post_language($post_id); $translations = $multilingual->get_post_translations($post_id); $default_lang = $multilingual->get_default_language(); $source_id = !empty($translations[$default_lang]) ? absint($translations[$default_lang]) : $post_id; $is_source = ($post_id === $source_id) || ($post_lang === $default_lang); $default_lang_name = strtoupper($default_lang); if (isset($available_langs[$default_lang])) { $dl = $available_langs[$default_lang]; $default_lang_name = is_object($dl) ? ($dl->name ?? strtoupper($default_lang)) : (is_array($dl) ? ($dl['name'] ?? strtoupper($default_lang)) : strtoupper($default_lang)); } $current_url = is_admin() ? (isset($_SERVER['REQUEST_URI']) ? home_url($_SERVER['REQUEST_URI']) : admin_url('post.php?post=' . $post_id . '&action=edit')) : get_permalink($post_id); $page_lang_data = [ 'post_id' => $post_id, 'source_id' => $source_id, 'is_source' => $is_source, 'post_lang' => $post_lang, 'default_lang' => $default_lang, 'default_lang_name' => $default_lang_name, 'translations' => $translations, 'available_langs' => $available_langs, 'current_url' => $current_url, ]; } } } // Get live license & word usage status $license_manager = class_exists('AITRFOEL_License_Manager_Server') ? AITRFOEL_License_Manager_Server::get_instance() : null; $license_status = $license_manager ? $license_manager->get_license_status() : []; $used = isset($license_status['words_used']) ? (int) $license_status['words_used'] : (int) ($license_status['words_translated'] ?? 0); $raw_limit = isset($license_status['word_limit']) ? (int) $license_status['word_limit'] : (int) ($license_status['total_words'] ?? 7200); $plan_name = !empty($license_status['plan_name']) ? $license_status['plan_name'] : (!empty($license_status['plan']) ? ucfirst($license_status['plan']) : 'Free'); $is_unlimited = ($raw_limit === -1 || !empty($license_status['unlimited']) || !empty($license_status['is_unlimited']) || strtolower($plan_name) === 'agency lifetime'); $limit = $is_unlimited ? -1 : ($raw_limit <= 0 ? 7200 : $raw_limit); $is_pro = (defined('AITRFOEL_VERSION_TYPE') && AITRFOEL_VERSION_TYPE === 'pro') || ($plan_name !== 'Free' && $plan_name !== 'free'); $pct = ($limit > 0 && !$is_unlimited) ? min(100, round(($used / $limit) * 100)) : 0; $is_limit_reached = (!$is_unlimited && $pct >= 100); // Calculate site translation completeness $score = 0; $total_pages = 0; $translated_pages = 0; if (class_exists('AITRFOEL_Admin_Menu')) { $admin_menu = AITRFOEL_Admin_Menu::get_instance(); if (method_exists($admin_menu, 'get_translation_stats')) { $stats = $admin_menu->get_translation_stats(); $score = $stats['score'] ?? 0; $total_pages = $stats['total'] ?? 0; $translated_pages = $stats['translated'] ?? 0; } } $dashboard_url = admin_url('admin.php?page=ai-translator-for-elementor-and-polylang'); $translate_all_url = admin_url('admin.php?page=ai-translator-for-elementor-and-polylang-translate-all'); $settings_url = admin_url('admin.php?page=ai-translator-for-elementor-and-polylang-settings'); $pricing_url = 'https://meeptech.com/products/ai-translator-for-elementor-polylang/?utm_source=wp-plugin&utm_medium=admin-bar&utm_campaign=pro-upgrade#pricing'; // 1. Primary Top Node $badge_html = ''; if ($is_limit_reached) { $badge_html = '' . esc_html__('Limit Reached', 'ai-translator-for-elementor-and-polylang') . ''; } elseif ($pct >= 80) { $badge_html = '' . esc_html(sprintf(__('%d%%', 'ai-translator-for-elementor-and-polylang'), $pct)) . ''; } $icon_svg = ''; $node_label = $has_page_context ? esc_html__('Meep Translate', 'ai-translator-for-elementor-and-polylang') : esc_html__('Meep', 'ai-translator-for-elementor-and-polylang'); $wp_admin_bar->add_node([ 'id' => 'aitrfoel-admin-bar-hub', 'title' => $icon_svg . '' . $node_label . '' . $badge_html, 'href' => $dashboard_url, 'meta' => [ 'title' => esc_attr__('Meep Translator Hub', 'ai-translator-for-elementor-and-polylang'), 'class' => 'aitrfoel-admin-bar-root', ], ]); // 2. Single Page Translation Submenu Items if ($has_page_context && $page_lang_data) { $pld = $page_lang_data; if ($pld['is_source']) { foreach ($pld['available_langs'] as $code => $lang) { if ($code === $pld['post_lang'] || $code === $pld['default_lang']) { continue; } $lang_name = is_object($lang) ? ($lang->name ?? strtoupper($code)) : (is_array($lang) ? ($lang['name'] ?? strtoupper($code)) : strtoupper($code)); $has_translation = isset($pld['translations'][$code]) && $pld['translations'][$code]; $trans_post_id = $has_translation ? absint($pld['translations'][$code]) : 0; $flag_html = class_exists('AITRFOEL_Language_Mapper') ? AITRFOEL_Language_Mapper::get_flag_html($code, 16, 'margin-right:6px;vertical-align:middle;') : ''; if ($has_translation && $trans_post_id) { $retrans_url = wp_nonce_url( add_query_arg([ 'action' => 'aitrfoel_admin_bar_translate', 'post_id' => $pld['source_id'], 'target_lang' => $code, 'redirect_to' => rawurlencode($pld['current_url']), ], admin_url('admin-post.php')), 'aitrfoel_ab_trans_' . $pld['source_id'] ); $wp_admin_bar->add_node([ 'parent' => 'aitrfoel-admin-bar-hub', 'id' => 'aitrfoel-bar-retrans-' . $code, 'title' => $flag_html . sprintf(esc_html__('Retranslate to %s (%s)', 'ai-translator-for-elementor-and-polylang'), esc_html($lang_name), strtoupper($code)), 'href' => esc_url($retrans_url), ]); $wp_admin_bar->add_node([ 'parent' => 'aitrfoel-admin-bar-hub', 'id' => 'aitrfoel-bar-edit-' . $code, 'title' => '' . sprintf(esc_html__('Edit %s Translation', 'ai-translator-for-elementor-and-polylang'), strtoupper($code)) . '', 'href' => esc_url(get_edit_post_link($trans_post_id)), ]); $wp_admin_bar->add_node([ 'parent' => 'aitrfoel-admin-bar-hub', 'id' => 'aitrfoel-bar-view-' . $code, 'title' => '' . sprintf(esc_html__('View %s Version', 'ai-translator-for-elementor-and-polylang'), strtoupper($code)) . '', 'href' => esc_url(get_permalink($trans_post_id)), ]); } else { $trans_url = wp_nonce_url( add_query_arg([ 'action' => 'aitrfoel_admin_bar_translate', 'post_id' => $pld['source_id'], 'target_lang' => $code, 'redirect_to' => rawurlencode($pld['current_url']), ], admin_url('admin-post.php')), 'aitrfoel_ab_trans_' . $pld['source_id'] ); $wp_admin_bar->add_node([ 'parent' => 'aitrfoel-admin-bar-hub', 'id' => 'aitrfoel-bar-trans-' . $code, 'title' => $flag_html . sprintf(esc_html__('Translate to %s (%s)', 'ai-translator-for-elementor-and-polylang'), esc_html($lang_name), strtoupper($code)), 'href' => esc_url($trans_url), ]); } } } else { $retrans_current_url = wp_nonce_url( add_query_arg([ 'action' => 'aitrfoel_admin_bar_translate', 'post_id' => $pld['source_id'], 'target_lang' => $pld['post_lang'], 'redirect_to' => rawurlencode($pld['current_url']), ], admin_url('admin-post.php')), 'aitrfoel_ab_trans_' . $pld['source_id'] ); $wp_admin_bar->add_node([ 'parent' => 'aitrfoel-admin-bar-hub', 'id' => 'aitrfoel-bar-retrans-current', 'title' => sprintf(esc_html__('Retranslate this page (from %s)', 'ai-translator-for-elementor-and-polylang'), strtoupper($pld['default_lang'])), 'href' => esc_url($retrans_current_url), ]); $wp_admin_bar->add_node([ 'parent' => 'aitrfoel-admin-bar-hub', 'id' => 'aitrfoel-bar-edit-source', 'title' => '' . sprintf(esc_html__('Edit Original (%s)', 'ai-translator-for-elementor-and-polylang'), strtoupper($pld['default_lang'])) . '', 'href' => esc_url(get_edit_post_link($pld['source_id'])), ]); $wp_admin_bar->add_node([ 'parent' => 'aitrfoel-admin-bar-hub', 'id' => 'aitrfoel-bar-view-source', 'title' => '' . sprintf(esc_html__('View Original (%s)', 'ai-translator-for-elementor-and-polylang'), strtoupper($pld['default_lang'])) . '', 'href' => esc_url(get_permalink($pld['source_id'])), ]); foreach ($pld['available_langs'] as $code => $lang) { if ($code === $pld['post_lang'] || $code === $pld['default_lang']) { continue; } $lang_name = is_object($lang) ? ($lang->name ?? strtoupper($code)) : (is_array($lang) ? ($lang['name'] ?? strtoupper($code)) : strtoupper($code)); $has_translation = isset($pld['translations'][$code]) && $pld['translations'][$code]; $trans_post_id = $has_translation ? absint($pld['translations'][$code]) : 0; $flag_html = class_exists('AITRFOEL_Language_Mapper') ? AITRFOEL_Language_Mapper::get_flag_html($code, 16, 'margin-right:6px;vertical-align:middle;') : ''; if ($has_translation && $trans_post_id) { $other_retrans_url = wp_nonce_url( add_query_arg([ 'action' => 'aitrfoel_admin_bar_translate', 'post_id' => $pld['source_id'], 'target_lang' => $code, 'redirect_to' => rawurlencode($pld['current_url']), ], admin_url('admin-post.php')), 'aitrfoel_ab_trans_' . $pld['source_id'] ); $wp_admin_bar->add_node([ 'parent' => 'aitrfoel-admin-bar-hub', 'id' => 'aitrfoel-bar-retrans-' . $code, 'title' => $flag_html . sprintf(esc_html__('Retranslate to %s (%s)', 'ai-translator-for-elementor-and-polylang'), esc_html($lang_name), strtoupper($code)), 'href' => esc_url($other_retrans_url), ]); $wp_admin_bar->add_node([ 'parent' => 'aitrfoel-admin-bar-hub', 'id' => 'aitrfoel-bar-view-' . $code, 'title' => '' . sprintf(esc_html__('View %s Version', 'ai-translator-for-elementor-and-polylang'), strtoupper($code)) . '', 'href' => esc_url(get_permalink($trans_post_id)), ]); } else { $other_trans_url = wp_nonce_url( add_query_arg([ 'action' => 'aitrfoel_admin_bar_translate', 'post_id' => $pld['source_id'], 'target_lang' => $code, 'redirect_to' => rawurlencode($pld['current_url']), ], admin_url('admin-post.php')), 'aitrfoel_ab_trans_' . $pld['source_id'] ); $wp_admin_bar->add_node([ 'parent' => 'aitrfoel-admin-bar-hub', 'id' => 'aitrfoel-bar-trans-' . $code, 'title' => $flag_html . sprintf(esc_html__('Translate to %s (%s)', 'ai-translator-for-elementor-and-polylang'), esc_html($lang_name), strtoupper($code)), 'href' => esc_url($other_trans_url), ]); } } } // Divider between single page actions and global hub items $wp_admin_bar->add_node([ 'parent' => 'aitrfoel-admin-bar-hub', 'id' => 'aitrfoel-bar-divider', 'title' => '
', 'href' => false, ]); } // 2. Submenu: Word Balance & Quota $bar_color = $is_unlimited ? '#10b981' : (($pct >= 100) ? '#ef4444' : (($pct >= 80) ? '#f59e0b' : '#10b981')); $usage_title = sprintf( '
%s: %s %s
', esc_html__('Plan', 'ai-translator-for-elementor-and-polylang'), esc_html($plan_name), esc_attr($bar_color), $is_unlimited ? esc_html__('Unlimited', 'ai-translator-for-elementor-and-polylang') : esc_html(sprintf(__('%s / %s words (%d%%)', 'ai-translator-for-elementor-and-polylang'), number_format($used), number_format($limit), $pct)), $is_unlimited ? 100 : $pct, esc_attr($bar_color) ); $wp_admin_bar->add_node([ 'parent' => 'aitrfoel-admin-bar-hub', 'id' => 'aitrfoel-bar-usage', 'title' => $usage_title, 'href' => $dashboard_url, ]); // 3. Submenu: Action / Upgrade / Giveaway (ONLY for free / unlicensed accounts) if (!$is_pro && !$is_unlimited) { if ($is_limit_reached) { // Free user limit reached CTA $wp_admin_bar->add_node([ 'parent' => 'aitrfoel-admin-bar-hub', 'id' => 'aitrfoel-bar-upgrade-promo', 'title' => '' . esc_html__('Upgrade to PRO (20% OFF: MEEP20)', 'ai-translator-for-elementor-and-polylang') . '', 'href' => $pricing_url, 'meta' => ['target' => '_blank'], ]); $wp_admin_bar->add_node([ 'parent' => 'aitrfoel-admin-bar-hub', 'id' => 'aitrfoel-bar-bonus-words', 'title' => '' . esc_html__('Claim +2,500 Bonus Words (Share)', 'ai-translator-for-elementor-and-polylang') . '', 'href' => $dashboard_url . '#bonus-words', ]); } else { $wp_admin_bar->add_node([ 'parent' => 'aitrfoel-admin-bar-hub', 'id' => 'aitrfoel-bar-upgrade-pro', 'title' => '' . esc_html__('Upgrade to PRO (Claude & DeepL)', 'ai-translator-for-elementor-and-polylang') . '', 'href' => $pricing_url, 'meta' => ['target' => '_blank'], ]); } } // 4. Submenu: Site Translation Score if ($total_pages > 0) { $score_text = sprintf( __('Site Progress: %d%% (%d/%d translated)', 'ai-translator-for-elementor-and-polylang'), $score, $translated_pages, $total_pages ); $wp_admin_bar->add_node([ 'parent' => 'aitrfoel-admin-bar-hub', 'id' => 'aitrfoel-bar-health', 'title' => '' . esc_html($score_text) . '', 'href' => $translate_all_url, ]); } // 5. Submenu: Quick Navigation $wp_admin_bar->add_node([ 'parent' => 'aitrfoel-admin-bar-hub', 'id' => 'aitrfoel-bar-dashboard-link', 'title' => esc_html__('Translation Dashboard', 'ai-translator-for-elementor-and-polylang'), 'href' => $dashboard_url, ]); $wp_admin_bar->add_node([ 'parent' => 'aitrfoel-admin-bar-hub', 'id' => 'aitrfoel-bar-queue-link', 'title' => esc_html__('Translate All Queue', 'ai-translator-for-elementor-and-polylang'), 'href' => $translate_all_url, ]); $wp_admin_bar->add_node([ 'parent' => 'aitrfoel-admin-bar-hub', 'id' => 'aitrfoel-bar-settings-link', 'title' => esc_html__('Settings Hub', 'ai-translator-for-elementor-and-polylang'), 'href' => $settings_url, ]); } /** * Custom CSS for Admin Bar styling */ public function render_admin_bar_css() { if (!is_admin_bar_showing()) { return; } ?> id, $allowed_screens, true) && strpos($screen->id, 'ai-translator') === false) { return; } // Check dismiss flag if (get_transient('aitrfoel_limit_notice_dismissed_' . get_current_user_id())) { return; } $license_manager = class_exists('AITRFOEL_License_Manager_Server') ? AITRFOEL_License_Manager_Server::get_instance() : null; $license_status = $license_manager ? $license_manager->get_license_status() : []; $used = isset($license_status['words_used']) ? (int) $license_status['words_used'] : (int) ($license_status['words_translated'] ?? 0); $raw_limit = isset($license_status['word_limit']) ? (int) $license_status['word_limit'] : 7200; $plan_name = !empty($license_status['plan_name']) ? $license_status['plan_name'] : (!empty($license_status['plan']) ? ucfirst($license_status['plan']) : 'Free'); $is_unlimited = ($raw_limit === -1 || !empty($license_status['unlimited']) || !empty($license_status['is_unlimited']) || strtolower($plan_name) === 'agency lifetime'); $limit = $is_unlimited ? -1 : ($raw_limit <= 0 ? 7200 : $raw_limit); if ($is_unlimited || $limit <= 0 || $used < $limit) { return; } $pricing_url = 'https://meeptech.com/products/ai-translator-for-elementor-polylang/?utm_source=wp-plugin&utm_medium=admin-bar&utm_campaign=pro-upgrade#pricing'; $dashboard_url = admin_url('admin.php?page=ai-translator-for-elementor-and-polylang'); ?>
MEEP20