get_migration_url(); ?>

1) : ?>

$plugin) : ?>

' . '' . ''; } /** * URL of the Setup Wizard migration step, when migration is still possible. * * The wizard redirects to the dashboard once completed, so the link is * only offered while the wizard is still accessible and at least one * detected plugin has a ThinkRank importer. * * @return string Migration URL or '' when unavailable */ private function get_migration_url(): string { if (!SEO_Plugin_Detector::has_importable_plugin()) { return ''; } if (get_option(Setup_Wizard::OPT_COMPLETED, false)) { return ''; } return admin_url('admin.php?page=' . Setup_Wizard::PAGE_SLUG); } /** * Enqueue notice scripts * * @param string $hook Current admin page hook * @return void */ public function enqueue_notice_scripts(string $hook): void { if (!SEO_Plugin_Detector::should_show_notice()) { return; } wp_enqueue_style( 'thinkrank-admin-notices', THINKRANK_PLUGIN_URL . 'static/css/admin-notices.css', [], THINKRANK_VERSION ); wp_add_inline_script('jquery', ' jQuery(document).ready(function($) { function thinkrankDismissSeoNotice() { $.post(ajaxurl, { action: "thinkrank_dismiss_seo_notice", nonce: "' . wp_create_nonce('thinkrank_seo_notice_nonce') . '" }, function(response) { if (response.success) { $(".thinkrank-seo-notice").fadeOut(); } }); } $(".thinkrank-dismiss-seo-notice").on("click", function(e) { e.preventDefault(); thinkrankDismissSeoNotice(); }); // Persist dismissal from the core notice X button too // (delegated — core injects the button after DOM ready) $(document).on("click", ".thinkrank-seo-notice .notice-dismiss", thinkrankDismissSeoNotice); $(".thinkrank-deactivate-seo-plugin").on("click", function(e) { e.preventDefault(); var $button = $(this); $button.prop("disabled", true); $.post(ajaxurl, { action: "thinkrank_deactivate_seo_plugin", plugin: $button.data("plugin"), nonce: "' . wp_create_nonce('thinkrank_seo_notice_nonce') . '" }, function(response) { if (response.success) { window.location.reload(); } else { $button.prop("disabled", false); } }); }); }); '); } /** * AJAX handler to dismiss SEO notice * * @return void */ public function ajax_dismiss_notice(): void { $nonce = sanitize_text_field(wp_unslash($_POST['nonce'] ?? '')); if (!wp_verify_nonce($nonce, 'thinkrank_seo_notice_nonce')) { wp_send_json_error('Security check failed'); } // The notice is an admin-facing plugin-conflict warning — only users who // can manage the plugin should be able to dismiss it. if (!current_user_can('edit_posts')) { wp_send_json_error('Insufficient permissions'); } SEO_Plugin_Detector::dismiss_notice(); wp_send_json_success(); } /** * AJAX handler to deactivate a conflicting SEO plugin. * * Only accepts a known-plugin slug; the plugin file(s) — including * premium companions — are resolved server-side by the detector. * * @return void */ public function ajax_deactivate_plugin(): void { $nonce = sanitize_text_field(wp_unslash($_POST['nonce'] ?? '')); if (!wp_verify_nonce($nonce, 'thinkrank_seo_notice_nonce')) { wp_send_json_error('Security check failed'); } if (!current_user_can('deactivate_plugins')) { wp_send_json_error('Insufficient permissions'); } $slug = sanitize_key(wp_unslash($_POST['plugin'] ?? '')); $files = SEO_Plugin_Detector::get_deactivatable_files($slug); if (empty($files)) { wp_send_json_error('Unknown plugin'); } deactivate_plugins($files); wp_send_json_success(); } }