# thinkrank/1.10.0/includes/admin/class-manager.php

ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console &amp; Local SEO, version 1.10.0. 845 lines.

- Page: https://pluginprobe.com/plugins/thinkrank/1.10.0/code/includes/admin/class-manager.php
- Raw: https://pluginprobe.com/plugins/thinkrank/1.10.0/raw/includes/admin/class-manager.php
- Modified: 2026-05-05T11:07:32+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/thinkrank/1.10.0/code/includes/admin/class-manager.php#L10-L20`.

```php
<?php

/**
 * Admin Manager Class
 * 
 * Handles WordPress admin interface integration
 * 
 * @package ThinkRank\Admin
 * @since 1.0.0
 */

declare(strict_types=1);

namespace ThinkRank\Admin;

use ThinkRank\Core\Settings;
use ThinkRank\Core\Database;
use ThinkRank\Admin\Metabox_Manager;
use ThinkRank\Admin\Bulk_Action_Manager;
use ThinkRank\Admin\Post_List_Filters;

// Prevent direct access
if (!defined('ABSPATH')) {
    exit;
}

/**
 * Admin Manager Class
 * 
 * Single Responsibility: Manage WordPress admin interface
 * 
 * @since 1.0.0
 */
class Manager {

    /**
     * Settings instance
     * 
     * @var Settings
     */
    private Settings $settings;

    /**
     * Database instance
     *
     * @var Database
     */
    private Database $database;

    /**
     * Metabox manager instance
     *
     * @var Metabox_Manager
     */
    private Metabox_Manager $metabox_manager;

    /**
     * Post list columns instance
     *
     * @var Post_List_Columns
     */
    private Post_List_Columns $post_list_columns;

    /**
     * Focus keyword AJAX handler instance
     *
     * @var Focus_Keyword_Ajax
     */
    private Focus_Keyword_Ajax $focus_keyword_ajax;

    /**
     * Bulk action manager instance
     *
     * @var Bulk_Action_Manager
     */
    private Bulk_Action_Manager $bulk_action_manager;

    /**
     * Post list filters instance
     *
     * @var Post_List_Filters
     */
    private Post_List_Filters $post_list_filters;

    /**
     * Admin pages
     *
     * @var array
     */
    private array $pages = [];

    /**
     * Constructor
     *
     * @param Settings $settings Settings instance
     * @param Database $database Database instance
     */
    public function __construct(?Settings $settings = null, ?Database $database = null) {
        $this->settings = $settings ?? new Settings();
        $this->database = $database ?? new Database();
        $this->metabox_manager = new Metabox_Manager($this->settings);
        $this->post_list_columns = new Post_List_Columns();
        $this->focus_keyword_ajax = new Focus_Keyword_Ajax();
        $this->bulk_action_manager = new Bulk_Action_Manager();
        $this->post_list_filters = new Post_List_Filters();
    }

    /**
     * Initialize admin interface
     *
     * @return void
     */
    public function init(): void {
        add_action('admin_menu', [$this, 'add_admin_menu']);
        add_action('admin_enqueue_scripts', [$this, 'enqueue_admin_scripts']);
        add_action('admin_init', [$this, 'handle_admin_init']);
        add_action('admin_notices', [$this, 'show_admin_notices']);
        add_action('tr_admin_notices', [$this, 'show_admin_notices']);
		add_action( 'in_admin_header', [ $this, 'remove_admin_notice' ], 99 );

        // AJAX handlers
        add_action('wp_ajax_thinkrank_dismiss_notice', [$this, 'dismiss_notice']);

        // Initialize metabox manager
        $this->metabox_manager->init();

        // Initialize post list columns
        $this->post_list_columns->init();

        // Initialize focus keyword AJAX handler
        $this->focus_keyword_ajax->init();

        // Initialize Bulk Action Manager
        $this->bulk_action_manager->init();

        // Initialize Post List Filters
        $this->post_list_filters->init();
    }

    /**
     * Add admin menu pages
     * 
     * @return void
     */
    public function add_admin_menu(): void {
        // Main menu page
        $this->pages['dashboard'] = add_menu_page(
            __('ThinkRank', 'thinkrank'),
            __('ThinkRank', 'thinkrank'),
            'manage_options',
            'thinkrank',
            [$this, 'render_dashboard_page'],
            $this->get_menu_icon(),
            30
        );

        // Dashboard submenu (same as main)
        $this->pages['dashboard_sub'] = add_submenu_page(
            'thinkrank',
            __('Dashboard', 'thinkrank'),
            __('Dashboard', 'thinkrank'),
            'manage_options',
            'thinkrank',
            [$this, 'render_dashboard_page']
        );

        // Essential SEO page (React tabbed interface)
        $this->pages['essential_seo'] = add_submenu_page(
            'thinkrank',
            __('Essential SEO', 'thinkrank'),
            __('Essential SEO', 'thinkrank'),
            'manage_options',
            'thinkrank-essential-seo',
            [$this, 'render_essential_seo_page']
        );

        // AI Tools page
        $this->pages['ai_tools'] = add_submenu_page(
            'thinkrank',
            __('AI Tools', 'thinkrank'),
            __('AI Tools', 'thinkrank'),
            'edit_posts',
            'thinkrank-ai-tools',
            [$this, 'render_ai_tools_page']
        );

        // Settings page
        $this->pages['settings'] = add_submenu_page(
            'thinkrank',
            __('Settings', 'thinkrank'),
            __('Settings', 'thinkrank'),
            'manage_options',
            'thinkrank-settings',
            [$this, 'render_settings_page']
        );

        // Usage Analytics page
        $this->pages['analytics'] = add_submenu_page(
            'thinkrank',
            __('Usage Analytics', 'thinkrank'),
            __('Usage Analytics', 'thinkrank'),
            'edit_posts',
            'thinkrank-analytics',
            [$this, 'render_analytics_page']
        );

        // Hook for page-specific initialization
        foreach ($this->pages as $page_hook) {
            add_action("load-{$page_hook}", [$this, 'load_admin_page']);
        }
    }

    /**
     * Enqueue admin scripts and styles
     *
     * APPROACH: Manual enqueuing with disabled webpack code splitting
     * - All dependencies bundled into main admin.js (677KB)
     * - Chart.js separated into charts.js (138KB) for performance
     * - No dynamic chunks - predictable loading order
     *
     * @param string $hook_suffix Current admin page hook
     * @return void
     */
    public function enqueue_admin_scripts(string $hook_suffix): void {
        // Only load on our admin pages
        if (!in_array($hook_suffix, $this->pages, true)) {
            return;
        }

        // Get asset files for cache busting
        $admin_asset_file = THINKRANK_PLUGIN_DIR . 'assets/admin.asset.php';
        $admin_asset_data = file_exists($admin_asset_file) ? include $admin_asset_file : [
            'dependencies' => [],
            'version' => THINKRANK_VERSION,
        ];

        // Enqueue Chart.js bundle only on pages that render charts (Analytics and Essential SEO Performance)
        $charts_asset_file = THINKRANK_PLUGIN_DIR . 'assets/charts.asset.php';
        $should_enqueue_charts = in_array($hook_suffix, [
            $this->pages['analytics'] ?? '',
            $this->pages['essential_seo'] ?? '',
        ], true);

        if ($should_enqueue_charts && file_exists($charts_asset_file)) {
            $charts_asset_data = include $charts_asset_file;
            wp_enqueue_script(
                'thinkrank-charts',
                THINKRANK_PLUGIN_URL . 'assets/charts.js',
                $charts_asset_data['dependencies'],
                $charts_asset_data['version'],
                true
            );
            // Add charts as dependency for admin script to ensure registration before use
            $admin_dependencies = array_merge($admin_asset_data['dependencies'], ['thinkrank-charts']);
        } else {
            // Do not load charts on pages that don't need it
            $admin_dependencies = $admin_asset_data['dependencies'];
        }

        wp_enqueue_script(
            'thinkrank-admin',
            THINKRANK_PLUGIN_URL . 'assets/admin.js',
            $admin_dependencies,
            $admin_asset_data['version'],
            true
        );

        // Add defer attribute for better performance
        wp_script_add_data('thinkrank-admin', 'defer', true);

        // Enqueue admin styles
        wp_enqueue_style(
            'thinkrank-admin',
            THINKRANK_PLUGIN_URL . 'assets/admin.css',
            ['wp-components'],
            $admin_asset_data['version']
        );

        // Enqueue WordPress media library for MediaPicker component
        wp_enqueue_media();

        // Localize script with data
        wp_localize_script('thinkrank-admin', 'thinkrankAdmin', [
            'apiUrl' => rest_url('thinkrank/v1/'),
            'nonce' => wp_create_nonce('wp_rest'),
            'restNonce' => wp_create_nonce('wp_rest'),
            'adminNonce' => wp_create_nonce('thinkrank_admin'),
            'currentUser' => wp_get_current_user()->ID,
            'capabilities' => $this->get_user_capabilities(),
            'settings' => $this->get_admin_settings(),
            'i18n' => $this->get_i18n_strings(),
            'isAdmin' => current_user_can('manage_options'),
            // Plugin version - directly available without API call
            'version' => THINKRANK_VERSION,
            // Site information for default values
            'siteName' => get_bloginfo('name'),
            'siteDescription' => get_bloginfo('description'),
            'siteUrl' => home_url(),
            'adminEmail' => get_option('admin_email'),
            // Post types for Global SEO navigation
            'postTypes' => $this->get_public_post_types(),
            // Pro detection flag
            'isPro' => defined('THINKRANK_PRO_VERSION'),
            // Data update frequency (Pro: daily, Free: every 3 days)
            'dataUpdateFrequency' => defined('THINKRANK_PRO_VERSION') ? 'daily' : '3days',
        ]);

        // Add welcome notice dismissal script
        if (get_option('thinkrank_show_welcome') && !$this->has_api_key_configured()) {
            wp_add_inline_script('thinkrank-admin', '
                jQuery(document).ready(function($) {
                    $(".thinkrank-dismiss-welcome").on("click", function(e) {
                        e.preventDefault();

                        $.post(ajaxurl, {
                            action: "thinkrank_dismiss_notice",
                            notice_type: "welcome",
                            nonce: thinkrankAdmin.adminNonce
                        }, function(response) {
                            $(".thinkrank-welcome-notice").fadeOut();
                        });
                    });
                });
            ');
        }
    }

    /**
     * Handle admin initialization
     *
     * @return void
     */
    public function handle_admin_init(): void {
        // Show welcome screen for new installations (only if no API key configured)
        if (get_option('thinkrank_show_welcome') && !$this->has_api_key_configured()) {
            add_action('admin_notices', [$this, 'show_welcome_notice']);
        }

        // Check for plugin updates
        $this->check_plugin_updates();
    }

    /**
     * Load admin page
     * 
     * @return void
     */
    public function load_admin_page(): void {
        // Add help tabs
        $this->add_help_tabs();

        // Add screen options
        $this->add_screen_options();
    }

    /**
     * Render dashboard page
     *
     * @return void
     */
    public function render_dashboard_page(): void {
        $this->render_admin_page('dashboard', [
            'title' => __('ThinkRank Dashboard', 'thinkrank'),
            'description' => __('AI-powered SEO optimization for WordPress', 'thinkrank'),
        ]);
    }

    /**
     * Render Essential SEO page
     *
     * @return void
     */
    public function render_essential_seo_page(): void {
        $this->render_admin_page('essential-seo', [
            'title' => __('Essential SEO', 'thinkrank'),
            'description' => __('Configure your site-wide SEO settings with AI-powered optimization', 'thinkrank'),
        ]);
    }

    /**
     * Render AI Tools page
     *
     * @return void
     */
    public function render_ai_tools_page(): void {
        $this->render_admin_page('ai-tools', [
            'title' => __('AI Tools', 'thinkrank'),
            'description' => __('AI-powered content tools including Content Planner and Metadata Generator', 'thinkrank'),
        ]);
    }

    /**
     * Render settings page
     *
     * @return void
     */
    public function render_settings_page(): void {
        $this->render_admin_page('settings', [
            'title' => __('ThinkRank Settings', 'thinkrank'),
            'description' => __('Configure your AI SEO settings', 'thinkrank'),
        ]);
    }



    /**
     * Render usage analytics page
     *
     * @return void
     */
    public function render_analytics_page(): void {
        $this->render_admin_page('analytics', [
            'title' => __('Usage Analytics', 'thinkrank'),
            'description' => __('Track your AI usage, costs, and plugin performance analytics', 'thinkrank'),
        ]);
    }

    /**
     * Render admin page template
     * 
     * @param string $page Page identifier
     * @param array $data Page data
     * @return void
     */
    private function render_admin_page(string $page, array $data): void {
?>
        <div class="wrap">
            <div id="thinkrank-<?php echo esc_attr($page); ?>" class="thinkrank-admin-page">
                <div class="thinkrank-loading">
					<img src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNjAiIGhlaWdodD0iNjAiIHZpZXdCb3g9IjAgMCA2MCA2MCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgIDxwYXRoIGQ9Ik0xMC4zNzY4IDQ4LjU0QzExLjMyODEgNDguNTQgMTIuMDk5MyA0Ny43Njg4IDEyLjA5OTMgNDYuODE3NUMxMi4wOTkzIDQ1Ljg2NjIgMTEuMzI4MSA0NS4wOTUgMTAuMzc2OCA0NS4wOTVDOS40MjU0OSA0NS4wOTUgOC42NTQzIDQ1Ljg2NjIgOC42NTQzIDQ2LjgxNzVDOC42NTQzIDQ3Ljc2ODggOS40MjU0OSA0OC41NCAxMC4zNzY4IDQ4LjU0WiIgZmlsbD0iIzAwMDMyOSIgZmlsbC1vcGFjaXR5PSIwLjA1Ii8+CiAgICA8cGF0aCBkPSJNMy45MTE3MiAzNy4zNjVDNS4wNjQ2MSAzNy4zNjUgNS45OTkyMiAzNi40MzA0IDUuOTk5MjIgMzUuMjc3NUM1Ljk5OTIyIDM0LjEyNDYgNS4wNjQ2MSAzMy4xOSAzLjkxMTcyIDMzLjE5QzIuNzU4ODIgMzMuMTkgMS44MjQyMiAzNC4xMjQ2IDEuODI0MjIgMzUuMjc3NUMxLjgyNDIyIDM2LjQzMDQgMi43NTg4MiAzNy4zNjUgMy45MTE3MiAzNy4zNjVaIiBmaWxsPSIjMDAwMzI5IiBmaWxsLW9wYWNpdHk9IjAuMSIvPgogICAgPHBhdGggZD0iTTMuOTExNzIgMjQuMzU1QzUuMjM3MiAyNC4zNTUgNi4zMTE3MiAyMy4yODA1IDYuMzExNzIgMjEuOTU1QzYuMzExNzIgMjAuNjI5NSA1LjIzNzIgMTkuNTU1IDMuOTExNzIgMTkuNTU1QzIuNTg2MjQgMTkuNTU1IDEuNTExNzIgMjAuNjI5NSAxLjUxMTcyIDIxLjk1NUMxLjUxMTcyIDIzLjI4MDUgMi41ODYyNCAyNC4zNTUgMy45MTE3MiAyNC4zNTVaIiBmaWxsPSIjMDAwMzI5IiBmaWxsLW9wYWNpdHk9IjAuMTUiLz4KICAgIDxwYXRoIGQ9Ik0xMC41NzE5IDEzLjEzQzEyLjA2OTkgMTMuMTMgMTMuMjg0NCAxMS45MTU2IDEzLjI4NDQgMTAuNDE3NUMxMy4yODQ0IDguOTE5NDQgMTIuMDY5OSA3LjcwNTAyIDEwLjU3MTkgNy43MDUwMkM5LjA3MzggNy43MDUwMiA3Ljg1OTM4IDguOTE5NDQgNy44NTkzOCAxMC40MTc1QzcuODU5MzggMTEuOTE1NiA5LjA3MzggMTMuMTMgMTAuNTcxOSAxMy4xM1oiIGZpbGw9IiMwMDAzMjkiIGZpbGwtb3BhY2l0eT0iMC4yIi8+CiAgICA8cGF0aCBkPSJNMjIgN0MyMy42NTY5IDcgMjUgNS42NTY4NSAyNSA0QzI1IDIuMzQzMTUgMjMuNjU2OSAxIDIyIDFDMjAuMzQzMSAxIDE5IDIuMzQzMTUgMTkgNEMxOSA1LjY1Njg1IDIwLjM0MzEgNyAyMiA3WiIgZmlsbD0iIzAwMDMyOSIgZmlsbC1vcGFjaXR5PSIwLjMiLz4KICAgIDxwYXRoIGQ9Ik0zNS4xMzY3IDYuNzA3NTJDMzYuOTMxNiA2LjcwNzUyIDM4LjM4NjcgNS4yNTI0NCAzOC4zODY3IDMuNDU3NTJDMzguMzg2NyAxLjY2MjU5IDM2LjkzMTYgMC4yMDc1MiAzNS4xMzY3IDAuMjA3NTJDMzMuMzQxOCAwLjIwNzUyIDMxLjg4NjcgMS42NjI1OSAzMS44ODY3IDMuNDU3NTJDMzEuODg2NyA1LjI1MjQ0IDMzLjM0MTggNi43MDc1MiAzNS4xMzY3IDYuNzA3NTJaIiBmaWxsPSIjMDAwMzI5IiBmaWxsLW9wYWNpdHk9IjAuNCIvPgogICAgPHBhdGggZD0iTTQ2LjUgMTRDNDguNDMzIDE0IDUwIDEyLjQzMyA1MCAxMC41QzUwIDguNTY3IDQ4LjQzMyA3IDQ2LjUgN0M0NC41NjcgNyA0MyA4LjU2NyA0MyAxMC41QzQzIDEyLjQzMyA0NC41NjcgMTQgNDYuNSAxNFoiIGZpbGw9IiMwMDAzMjkiIGZpbGwtb3BhY2l0eT0iMC41Ii8+CiAgICA8cGF0aCBkPSJNNTMgMjZDNTUuMjA5MSAyNiA1NyAyNC4yMDkxIDU3IDIyQzU3IDE5Ljc5MDkgNTUuMjA5MSAxOCA1MyAxOEM1MC43OTA5IDE4IDQ5IDE5Ljc5MDkgNDkgMjJDNDkgMjQuMjA5MSA1MC43OTA5IDI2IDUzIDI2WiIgZmlsbD0iIzAwMDMyOSIgZmlsbC1vcGFjaXR5PSIwLjYiLz4KICAgIDxwYXRoIGQ9Ik01My41IDQwQzU1Ljk4NTMgNDAgNTggMzcuOTg1MyA1OCAzNS41QzU4IDMzLjAxNDcgNTUuOTg1MyAzMSA1My41IDMxQzUxLjAxNDcgMzEgNDkgMzMuMDE0NyA0OSAzNS41QzQ5IDM3Ljk4NTMgNTEuMDE0NyA0MCA1My41IDQwWiIgZmlsbD0iIzAwMDMyOSIgZmlsbC1vcGFjaXR5PSIwLjciLz4KICAgIDxwYXRoIGQ9Ik00NyA1MkM0OS43NjE0IDUyIDUyIDQ5Ljc2MTQgNTIgNDdDNTIgNDQuMjM4NiA0OS43NjE0IDQyIDQ3IDQyQzQ0LjIzODYgNDIgNDIgNDQuMjM4NiA0MiA0N0M0MiA0OS43NjE0IDQ0LjIzODYgNTIgNDcgNTJaIiBmaWxsPSIjMDAwMzI5IiBmaWxsLW9wYWNpdHk9IjAuOCIvPgogICAgPHBhdGggZD0iTTM1LjUgNTlDMzguNTM3NiA1OSA0MSA1Ni41Mzc2IDQxIDUzLjVDNDEgNTAuNDYyNCAzOC41Mzc2IDQ4IDM1LjUgNDhDMzIuNDYyNCA0OCAzMCA1MC40NjI0IDMwIDUzLjVDMzAgNTYuNTM3NiAzMi40NjI0IDU5IDM1LjUgNTlaIiBmaWxsPSIjMDAwMzI5IiBmaWxsLW9wYWNpdHk9IjAuOSIvPgogICAgPHBhdGggZD0iTTIyIDU5QzI1LjMxMzcgNTkgMjggNTYuMzEzNyAyOCA1M0MyOCA0OS42ODYzIDI1LjMxMzcgNDcgMjIgNDdDMTguNjg2MyA0NyAxNiA0OS42ODYzIDE2IDUzQzE2IDU2LjMxMzcgMTguNjg2MyA1OSAyMiA1OVoiIGZpbGw9IiMwMDAzMjkiLz4KPC9zdmc+Cg==" alt="" aria-hidden="true" class="components-spinner thinkrank-svg-spinner thinkrank-animate-spin" style="width: 60px; height: 60px; display: inline-block; vertical-align: middle;">
                    <p><?php esc_html_e('Loading ThinkRank...', 'thinkrank'); ?></p>
                </div>
            </div>
        </div>
    <?php
    }

    /**
     * Add meta boxes to post edit screens
     * 
     * @return void
     */
    public function add_meta_boxes(): void {
        $post_types = get_post_types(['public' => true]);

        foreach ($post_types as $post_type) {
            add_meta_box(
                'thinkrank-seo',
                __('ThinkRank SEO', 'thinkrank'),
                [$this, 'render_seo_meta_box'],
                $post_type,
                'normal',
                'high'
            );
        }
    }

    /**
     * Render SEO meta box
     * 
     * @param \WP_Post $post Current post object
     * @return void
     */
    public function render_seo_meta_box(\WP_Post $post): void {
        wp_nonce_field('thinkrank_meta_box', 'thinkrank_meta_box_nonce');

        echo '<div id="thinkrank-meta-box" data-post-id="' . esc_attr($post->ID) . '">';
        echo '<div class="thinkrank-loading"><div class="spinner is-active"></div></div>';
        echo '</div>';
    }

    /**
     * Save meta box data
     * 
     * @param int $post_id Post ID
     * @return void
     */
    public function save_meta_boxes(int $post_id): void {
        // Verify nonce
        if (!isset($_POST['thinkrank_meta_box_nonce'])) {
            return;
        }

        $nonce = sanitize_text_field(wp_unslash($_POST['thinkrank_meta_box_nonce']));
        if (!wp_verify_nonce($nonce, 'thinkrank_meta_box')) {
            return;
        }

        // Check permissions
        if (!current_user_can('edit_post', $post_id)) {
            return;
        }

        // Save meta data (handled by AJAX in React components)
        do_action('thinkrank_save_post_meta', $post_id, $_POST);
    }

    /**
     * Show admin notices
     * 
     * @return void
     */
    public function show_admin_notices(): void {
        // Implementation will be added in next iteration
    }

    /**
     * Show welcome notice
     * 
     * @return void
     */
    public function show_welcome_notice(): void {
    ?>
        <div class="notice notice-success is-dismissible thinkrank-welcome-notice">
            <h3><?php esc_html_e('Welcome to ThinkRank!', 'thinkrank'); ?></h3>
            <p><?php esc_html_e('Thank you for installing ThinkRank. Get started by configuring your AI settings.', 'thinkrank'); ?></p>
            <p>
                <a href="<?php echo esc_url(admin_url('admin.php?page=thinkrank-settings')); ?>" class="button button-primary">
                    <?php esc_html_e('Configure Settings', 'thinkrank'); ?>
                </a>
                <a href="#" class="button thinkrank-dismiss-welcome">
                    <?php esc_html_e('Dismiss', 'thinkrank'); ?>
                </a>
            </p>
        </div>
<?php
    }

    /**
     * Dismiss notice via AJAX
     * 
     * @return void
     */
    public function dismiss_notice(): void {
        check_ajax_referer('thinkrank_admin', 'nonce');

        $notice_type = sanitize_key($_POST['notice_type'] ?? '');

        if ($notice_type === 'welcome') {
            delete_option('thinkrank_show_welcome');
        }

        wp_die();
    }

    /**
     * Check if API key is configured
     *
     * @return bool True if at least one API key is configured
     */
    private function has_api_key_configured(): bool {
        $settings = new \ThinkRank\Core\Settings();
        $openai_key = $settings->get('openai_api_key');
        $claude_key = $settings->get('claude_api_key');

        return !empty($openai_key) || !empty($claude_key);
    }

    /**
     * Get menu icon
     *
     * @return string Menu icon
     */
    private function get_menu_icon(): string {
        return 'data:image/svg+xml;base64,' . base64_encode(
            '<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
                <g clipPath="url(#thinkrank-clip)">
                    <g filter="url(#thinkrank-shadow)">
                        <circle cx="14" cy="9.2" r="1.3" fill="#a7aaad"/>
                    </g>
                    <path d="M19.5 7v5.3c0 2.4 0 3.6-.5 4.5-.4.8-1 1.4-1.8 1.8-.9.5-2.1.5-4.5.5H7.3c-2.4 0-3.6 0-4.5-.5-.8-.4-1.4-1-1.8-1.8-.2-.3-.3-.7-.4-1.1.5-.4.9-.6 1.3-.7.5-.2.9-.2 1.4-.2.7.1 1.3.2 2 .3.7.1 1.4.2 2.1.1 1.5-.3 2.5-1 3.4-2 .5-.5.9-1 1.4-1.5.3-.3.6-.7.9-1 .3.1.6.2.9.2.9 0 1.7-.8 1.7-1.7 0-.2 0-.4-.1-.6.7-.4 1.4-.8 2.1-1.1.6-.3 1.2-.6 1.6-.8v.4zM12.5 0c2.4 0 3.6 0 4.5.5.8.4 1.4 1 1.8 1.8.4.7.5 1.6.5 3.1-.1 0-.2.1-.3.1-.5.2-1.1.5-1.8.8-.7.3-1.5.7-2.2 1.1-.3-.3-.7-.4-1.1-.4-.9 0-1.7.8-1.7 1.7 0 .3.1.6.3.9-.3.4-.6.7-.9 1-.5.6-.9 1.1-1.3 1.5-.9.9-1.8 1.5-3 1.7-.6.1-1.2.1-1.8 0-.6-.1-1.3-.3-2-.4-.6-.1-1.2-.1-1.8.1-.3.1-.7.3-1 .5 0-.6 0-1.4 0-2.3V7c0-2.4 0-3.6.5-4.5.4-.8 1-1.4 1.8-1.8C3.9 0 5.1 0 7.5 0h5zm-5.8 8.2c0-.1-.1-.1-.2 0l-.2.9c0 0 0 .1-.1.1l-.9.2c-.1 0-.1.1 0 .1l.9.2c0 0 .1 0 .1.1l.2.9c0 .1.1.1.2 0l.2-.9c0 0 0-.1.1-.1l.9-.2c.1 0 .1-.1 0-.1l-.9-.2c0 0-.1 0-.1-.1l-.2-.9zm8.8-.4c0 .1 0 .2 0 .3 0 .7-.6 1.3-1.3 1.3-.2 0-.4 0-.5-.1.1-.1.2-.2.3-.3.4-.4.9-.8 1.5-1.2zm-1.3-1c.3 0 .5.1.7.2-.6.4-1.1.8-1.5 1.2l-.1.1c-.1.1-.2.2-.3.3-.1-.2-.1-.4-.1-.6 0-.7.6-1.2 1.3-1.2zM8.6 2.5c-.1-.2-.4-.2-.4 0l-.4 1.4c0 .1-.1.1-.1.1L6.2 4.4c-.2.1-.2.4 0 .4l1.4.4c.1 0 .1.1.1.1l.4 1.4c.1.2.4.2.4 0l.4-1.4c0-.1.1-.1.1-.1l1.4-.4c.2-.1.2-.4 0-.4L8.9 4c-.1 0-.1-.1-.1-.1L8.6 2.5z" fill="#a7aaad"/>
                </g>
                <defs>
                    <filter id="thinkrank-shadow" x="11.2" y="7.2" width="5.6" height="5.6" filterUnits="userSpaceOnUse" colorInterpolationFilters="sRGB">
                        <feFlood floodOpacity="0" result="BackgroundImageFix"/>
                        <feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
                        <feOffset dy="0.7"/>
                        <feGaussianBlur stdDeviation="0.7"/>
                        <feComposite in2="hardAlpha" operator="out"/>
                        <feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.15 0"/>
                        <feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
                        <feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
                    </filter>
                    <clipPath id="thinkrank-clip">
                        <rect width="20" height="20" rx="5.5" fill="white"/>
                    </clipPath>
                </defs>
            </svg>'
        );
    }

    /**
     * Get user capabilities for current user
     * 
     * @return array User capabilities
     */
    private function get_user_capabilities(): array {
        return [
            'manage_settings' => current_user_can('manage_options'),
            'view_analytics' => current_user_can('edit_posts'),

            'use_ai_features' => current_user_can('edit_posts'),
        ];
    }

    /**
     * Get admin settings for JavaScript
     * 
     * @return array Admin settings
     */
    private function get_admin_settings(): array {
        return [

            'ai_provider' => $this->settings->get('ai_provider', 'openai'),
            'cache_duration' => $this->settings->get('cache_duration', 3600),
        ];
    }

    /**
     * Get internationalization strings
     *
     * @return array I18n strings
     */
    private function get_i18n_strings(): array {
        return [
            'loading' => __('Loading...', 'thinkrank'),
            'error' => __('An error occurred', 'thinkrank'),
            'success' => __('Success!', 'thinkrank'),
            'confirm' => __('Are you sure?', 'thinkrank'),
            'cancel' => __('Cancel', 'thinkrank'),
            'save' => __('Save', 'thinkrank'),
        ];
    }

    /**
     * Get all public post types for SEO configuration
     *
     * @return array Post types data
     */
    private function get_public_post_types(): array {
        // Get all public post types (both built-in and custom)
        $post_types = get_post_types([
            'public' => true
        ], 'objects');

        $post_types_data = [];

        foreach ($post_types as $post_type) {
            // Skip certain post types that shouldn't have SEO settings
            $excluded_types = ['elementor_library', 'oceanwp_library', 'ae_global_templates'];
            if (in_array($post_type->name, $excluded_types)) {
                continue;
            }

            $post_types_data[] = [
                'name' => $post_type->name,
                'slug' => $post_type->name,
                'label' => $post_type->label,
                'singular_name' => $post_type->labels->singular_name ?? $post_type->label,
                'plural_name' => $post_type->label,
                'public' => $post_type->public,
                'has_archive' => $post_type->has_archive,
                'hierarchical' => $post_type->hierarchical,
            ];
        }

        return $post_types_data;
    }

    /**
     * Add help tabs
     * 
     * @return void
     */
    private function add_help_tabs(): void {
        $screen = get_current_screen();

        $screen->add_help_tab([
            'id' => 'thinkrank-overview',
            'title' => __('Overview', 'thinkrank'),
            'content' => '<p>' . __('ThinkRank.ai helps you optimize your content with AI-powered SEO suggestions.', 'thinkrank') . '</p>',
        ]);

        $screen->set_help_sidebar(
            '<p><strong>' . __('For more information:', 'thinkrank') . '</strong></p>' .
                '<p><a href="https://thinkrank.ai/docs" target="_blank">' . __('Documentation', 'thinkrank') . '</a></p>' .
                '<p><a href="https://thinkrank.ai/support" target="_blank">' . __('Support', 'thinkrank') . '</a></p>'
        );
    }

    /**
     * Add screen options
     * 
     * @return void
     */
    private function add_screen_options(): void {
        // Screen options will be added as needed
    }

    /**
     * Check for plugin updates
     *
     * @return void
     */
    private function check_plugin_updates(): void {
        $current_version = get_option('thinkrank_version');

        if (version_compare($current_version, THINKRANK_VERSION, '<')) {
            // Handle plugin update
            do_action('thinkrank_plugin_updated', $current_version, THINKRANK_VERSION);
            update_option('thinkrank_version', THINKRANK_VERSION);
        }
    }

    /**
     * Get admin styles
     *
     * @return string CSS styles
     */
    private function get_admin_styles(): string {
        return '
            .thinkrank-loading {
                display: flex;
                flex-direction: column;
                align-items: center;
                justify-content: center;
                padding: 40px 20px;
                text-align: center;
            }

            .thinkrank-loading .spinner {
                margin-bottom: 16px;
            }

            .thinkrank-loading p {
                margin: 0;
                color: #666;
                font-size: 14px;
            }

            .thinkrank-app {
                font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
            }

            .thinkrank-header {
                display: flex;
                justify-content: space-between;
                align-items: center;
                padding: 20px 0;
                border-bottom: 1px solid #ddd;
                margin-bottom: 20px;
            }

            .thinkrank-header h1 {
                margin: 0;
                font-size: 24px;
                font-weight: 600;
            }

            .thinkrank-header .version {
                font-size: 12px;
                color: #666;
                font-weight: normal;
                margin-left: 8px;
            }

            .thinkrank-header .tagline {
                margin: 4px 0 0 0;
                color: #666;
                font-size: 14px;
            }



            .thinkrank-dashboard-stats {
                display: grid;
                grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
                gap: 20px;
                margin-top: 20px;
            }

            .stat-card {
                background: #f9f9f9;
                padding: 20px;
                border-radius: 8px;
                text-align: center;
                border: 1px solid #ddd;
            }

            .stat-card h3 {
                margin: 0 0 10px 0;
                font-size: 14px;
                color: #666;
                text-transform: uppercase;
                letter-spacing: 0.5px;
            }

            .stat-number {
                font-size: 32px;
                font-weight: 700;
                color: #0073aa;
                margin: 0;
                line-height: 1;
            }

            .stat-label {
                margin: 4px 0 0 0;
                font-size: 12px;
                color: #666;
            }

            .thinkrank-error {
                padding: 20px;
            }

            .thinkrank-error .notice {
                margin: 0;
            }
        ';
    }

	public function remove_admin_notice() {
		$current_screen = get_current_screen();
		if ( in_array( $current_screen->id, [
				'toplevel_page_thinkrank',
				'thinkrank_page_thinkrank-essential-seo',
				'thinkrank_page_thinkrank-ai-tools',
				'thinkrank_page_thinkrank-settings',
				'thinkrank_page_thinkrank-analytics',
				'thinkrank_page_thinkrank-license'
		] ) ) {

			remove_all_actions( 'user_admin_notices' );
			remove_all_actions( 'admin_notices' );
			remove_all_actions( 'all_admin_notices' );
			remove_all_actions( 'network_admin_notices' );

			// To showing notice in EA settings page we have to use 'eael_admin_notices' action hook
			add_action( 'admin_notices', function () {
				do_action( 'tr_admin_notices' );
			} );
		}
	}
}

```
