admin_url('admin-ajax.php'), 'nonce' => wp_create_nonce('af_translate_secure_stream') )); } public /** * Register and securely enqueue admin-side workspace automation mechanisms * * @param string $hook The structural current admin page identifier slug. */ function af_translate_admin_dashboard_scripts($hook) { // Hard restriction: Only inject assets on the exact plugin administration screen hooks if (strpos($hook, 'af-translate') === false) { return; } // Safely register and queue the independent JavaScript controller asset file wp_enqueue_script( 'af-translate-dashboard-script', AF_TRANSLATE_URL .'assets/js/project-dashboard.js', // Make sure path maps relative to your file location array('jquery'), '1.0.0', true // Forces execution array down into bottom page footer layout tree ); // Create the parameter data object payload and append translatable interface alerts wp_localize_script('af-translate-dashboard-script', 'afTranslateDashboard', array( 'ajaxurl' => admin_url('admin-ajax.php'), 'nonce' => wp_create_nonce('af_translate_secure_action'), // Ensure this matches your Ajax token checks 'strings' => array( 'confirmSync' => esc_html__('Sync this language file with the master template? This updates new customization strings without destroying existing translations.', 'af-translate'), 'confirmDelete' => esc_html__('Are you sure you want to permanently delete this translation file and its compiled machine code?', 'af-translate'), 'errorDelete' => esc_html__('Failed to delete the selected file.', 'af-translate'), ) )); } /** * Enqueue control mechanisms for the language initialization view layout wizard * * @param string $hook The administrative window path signature string. */ public function af_translate_new_language_scripts($hook) { // Only target screens tied to our localization engine workspace configuration if (strpos($hook, 'af-translate') === false) { return; } // Register script asset file independently wp_enqueue_script( 'af-translate-new-lang-script', AF_TRANSLATE_URL .'assets/js/new-language.js', // Map relative path context variables accurately array('jquery'), '1.0.0', true ); // Bind nonces and multi-lingual string matrices cleanly to the script execution hook wp_localize_script('af-translate-new-lang-script', 'afTranslateNewLang', array( 'ajaxurl' => admin_url('admin-ajax.php'), 'nonce' => wp_create_nonce('af_translate_secure_action'), // Keep consistent with back-end ajax checks 'strings' => array( 'loadingText' => esc_html__('Analyzing bundle infrastructure...', 'af-translate'), 'buttonDefault' => esc_html__('Start translating', 'af-translate'), 'errorPrefix' => esc_html__('Error: ', 'af-translate'), 'errorDefault' => esc_html__('Failed to initialize localized dataset parameters.', 'af-translate'), ) )); } /** * Directs administrative action requests and checks system capabilities. */ public function render_workspace_router() { // Defensive Capability Guard: Immediately stop processing if user lacks permissions if (!current_user_can('manage_options')) { wp_die(esc_html__('Security Exception: You do not have sufficient permissions to access this page.', 'af-translate')); } // Determine current tab view context based on submenu page slugs natively // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only page routing navigation parameter. $current_page = isset($_GET['page']) ? sanitize_text_field(wp_unslash($_GET['page'])) : 'af-translate'; $tab = 'overview'; if ('af-translate-plugins' === $current_page) { $tab = 'plugins'; } elseif ('af-translate-themes' === $current_page) { $tab = 'themes'; } else { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only page layout routing tab state parameter. $tab = isset($_GET['tab']) ? sanitize_key(wp_unslash($_GET['tab'])) : 'overview'; } // Sanitize slug inputs cleanly using sanitize_key to completely avoid directory traversal attacks // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only component slug identifier mapping parameter. $view = isset($_GET['view']) ? sanitize_key(wp_unslash($_GET['view'])) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only component classification routing parameter. $type = isset($_GET['type']) ? sanitize_key(wp_unslash($_GET['type'])) : 'theme'; echo '
'; if (!empty($view)) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only secondary panel layout navigation handler parameter. $action = isset($_GET['action']) ? sanitize_key(wp_unslash($_GET['action'])) : 'dashboard'; switch ($action) { case 'edit': // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only localization target tracking parameter. $lang_target = isset($_GET['lang']) ? sanitize_key(wp_unslash($_GET['lang'])) : ''; AF_Translate_Editor_View::render($view, $type, $lang_target); break; case 'setup': AF_Translate_Project_Config::render_setup_panel($view, $type); break; case 'new-lang': AF_Translate_Project_Config::render_new_language_screen($view, $type); break; case 'dashboard': default: AF_Translate_Project_Config::render_project_dashboard($view, $type); break; } } else { $this->render_global_header(); $this->render_nav_tabs($tab); if ('overview' === $tab) { $this->render_overview_matrix(); } elseif ('plugins' === $tab) { $this->render_all_extensions_matrix('plugin'); } else { $this->render_all_extensions_matrix('theme'); } } echo '
'; } /** * Renders workspace branding interface. */ private function render_global_header() { ?>

get_stylesheet(); $theme_summary = AF_Translate_Analyzer::get_component_summary($theme_slug, 'theme'); $active_plugins = get_option('active_plugins'); ?>

get('Name')); ?> ' . esc_html__('POT Discovered', 'af-translate') . '' : '' . esc_html__('Missing Template', 'af-translate') . ''; ?>

'; } ?>
' . esc_html__('POT Discovered', 'af-translate') . '' : '' . esc_html__('No POT Found', 'af-translate') . ''; ?>
' . esc_html__('No active plugins discovered.', 'af-translate') . '

$data) { $slug = ('plugin' === $type) ? dirname($key) : $key; if ('.' === $slug) { $slug = basename($key, '.php'); } $name = ('plugin' === $type) ? $data['Name'] : $data->get('Name'); $is_active = ('plugin' === $type) ? is_plugin_active($key) : ($key === wp_get_theme()->get_stylesheet()); $domain = ('plugin' === $type) ? (!empty($data['TextDomain']) ? $data['TextDomain'] : $slug) : ($data->get('TextDomain') ? $data->get('TextDomain') : $slug); $target_menu_page = ('plugin' === $type) ? 'af-translate-plugins' : 'af-translate-themes'; ?>
' . esc_html__('Active', 'af-translate') . '' : '' . esc_html__('Inactive', 'af-translate') . ''; ?>