admin = $admin; } /** * @param Metasync_Admin $admin * @return self */ public static function get_instance(Metasync_Admin $admin): self { if (null === self::$instance || self::$instance->admin !== $admin) { self::$instance = new self($admin); } return self::$instance; } // ------------------------------------------------------------------ // Dashboard iframe (~200 lines) // ------------------------------------------------------------------ public function create_admin_dashboard_iframe() { $general_options = Metasync::get_option('general'); $otto_pixel_uuid = isset($general_options['otto_pixel_uuid']) ? $general_options['otto_pixel_uuid'] : ''; $api_key = isset($general_options['searchatlas_api_key']) ? $general_options['searchatlas_api_key'] : ''; $hide_dashboard = $general_options['hide_dashboard_framework'] ?? false; if ($hide_dashboard) { $this->admin->render_layout_open('Dashboard', 'dashboard', 'Overview of your SEO performance and plugin status.'); ?>

Dashboard Disabled

The dashboard is currently disabled.

admin->render_layout_close(false); return; } if (!$this->admin->is_heartbeat_connected()) { $this->admin->render_layout_open('Dashboard', 'dashboard', 'Overview of your SEO performance and plugin status.'); ?>

Setup Wizard

Run the setup wizard to configure your plugin, import from other SEO plugins, and optimize your settings in just a few minutes.

Start Setup Wizard

Authentication Required

You need to authenticate with to access the dashboard.

Go to Settings & Connect
admin->render_layout_close(false); return; } $jwt_token = $this->admin->get_fresh_jwt_token(); if ($jwt_token) { $jwt_parts = explode('.', $jwt_token); $jwt_header_info = count($jwt_parts) >= 2 ? 'Valid format (' . count($jwt_parts) . ' parts)' : 'Invalid format'; } else { } $public_hash = false; if ($jwt_token && $otto_pixel_uuid) { $public_hash = $this->admin->fetch_public_hash($otto_pixel_uuid, $jwt_token); if ($public_hash) { } else { } } else { $missing_params = []; if (empty($jwt_token)) $missing_params[] = 'JWT_TOKEN'; if (empty($otto_pixel_uuid)) $missing_params[] = 'OTTO_UUID'; } $dashboard_domain = Metasync_Admin::get_effective_dashboard_domain(); if ($public_hash) { $iframe_url = $dashboard_domain . '/seo-automation-v3/public?uuid=' . urlencode($otto_pixel_uuid) . '&category=onpage_optimizations&subGroup=page_title&public_hash=' . urlencode($public_hash); } else { $iframe_url = $dashboard_domain . '/seo-automation-v3/tasks?uuid=' . urlencode($otto_pixel_uuid) . '&category=All&Embed=True'; if ($jwt_token) { $iframe_url .= '&jwtToken=' . urlencode($jwt_token) . '&impersonate=1'; } else { } } $iframe_url .= '&source=wordpress-plugin-iframe'; $whitelabel_company_name = Metasync::get_whitelabel_company_name(); if ($whitelabel_company_name) { $iframe_url .= '&whitelabel=' . urlencode($whitelabel_company_name); } $whitelabel_settings = Metasync::get_whitelabel_settings(); $is_whitelabel_domain = !empty($whitelabel_settings['domain']); $this->admin->render_layout_open('Dashboard', 'dashboard', 'Overview of your SEO performance and plugin status.'); ?> admin->render_layout_close(false); } // ------------------------------------------------------------------ // Settings page (~1000 lines) // ------------------------------------------------------------------ public function create_admin_settings_page() { if (isset($_REQUEST['metasync_password_reset'])) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- routing check, the reset form verifies its own nonce Metasync_Admin_Ajax::instance()->render_password_reset_page(); return; } $active_tab = isset($_GET['tab']) ? sanitize_key( wp_unslash( $_GET['tab'] ) ) : 'general'; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only tab selection $whitelabel_settings = Metasync::get_whitelabel_settings(); $user_password = $whitelabel_settings['settings_password'] ?? ''; $hide_settings_enabled = !empty($whitelabel_settings['hide_settings']); $protected_tabs = []; if (!empty($user_password)) { $protected_tabs[] = 'whitelabel'; } if ($hide_settings_enabled && !empty($user_password)) { $protected_tabs = ['general', 'whitelabel', 'advanced']; } $password_protection_enabled = false; $password_validated = false; $password_error = ''; if (in_array($active_tab, $protected_tabs)) { $password_protection_enabled = !empty($user_password); $auth = new Metasync_Auth_Manager('whitelabel', 1800); $password_validated = $auth->has_access(); if (isset($_POST['whitelabel_password_submit']) && !$password_validated) { // phpcs:ignore WordPress.Security.NonceVerification.Missing -- read-only access check for a display message $password_error = 'Incorrect password. Please try again.'; } } $is_authenticated = $password_validated; $whitelabel_otto_name = Metasync::get_whitelabel_otto_name(); $page_slug = Metasync_Admin::$page_slug; ?> admin->render_layout_open('Settings', $settings_current_page, 'Manage all plugin settings and configuration.'); ?> *

* Clear all caches at once
* This will slow down your site until caches are rebuilt * *

* */ ?>

Protected Section

❌ Access Denied:
Forgot Password?

Security Tip: You can set a custom password in the White Label Settings to protect this section.

General Configuration

Configure your API, plugin features, caching, and general settings.

render_lock_button('general'); ?>
✅ Access Granted: You have successfully authenticated and can now modify settings.
admin->render_accordion_sections(Metasync_Admin::$page_slug . '_general'); ?>

Breadcrumb settings now live on their own page: Breadcrumbs.

Content Genius Synchronization

Sync your categories and user/author data with .

Setup Wizard

Run the setup wizard to configure your plugin, import from other SEO plugins, and optimize your settings in just a few minutes.

Start Setup Wizard

White Label Branding

Customize the plugin appearance with your own branding and logo.

render_lock_button('whitelabel'); ?>
✅ Access Granted: You have successfully authenticated and can now modify white label settings.

Color Palette

Customize the plugin color scheme for both dark and light themes. Changes preview instantly.

array( 'label' => 'Background', 'hint' => 'Main page background behind all content', 'dark' => '#0f1419', 'light' => '#f8f9fa', ), 'dashboard-card-bg' => array( 'label' => 'Card Background', 'hint' => 'Background of cards, panels, and content boxes', 'dark' => '#1a1f26', 'light' => '#ffffff', ), 'dashboard-card-hover' => array( 'label' => 'Card Hover', 'hint' => 'Card background when you hover over it', 'dark' => '#222831', 'light' => '#f1f3f5', ), 'dashboard-text-primary' => array( 'label' => 'Primary Text', 'hint' => 'Headings, body text, and main content', 'dark' => '#ffffff', 'light' => '#1a1f26', ), 'dashboard-text-secondary' => array( 'label' => 'Secondary Text', 'hint' => 'Descriptions, hints, and less important text', 'dark' => '#9ca3af', 'light' => '#6b7280', ), 'dashboard-accent' => array( 'label' => 'Accent Color', 'hint' => 'Buttons, links, and highlighted elements', 'dark' => '#3b82f6', 'light' => '#3b82f6', ), 'dashboard-accent-hover' => array( 'label' => 'Accent Hover', 'hint' => 'Buttons and links when hovered', 'dark' => '#2563eb', 'light' => '#2563eb', ), 'dashboard-success' => array( 'label' => 'Success', 'hint' => 'Success messages, connected status, positive indicators', 'dark' => '#10b981', 'light' => '#10b981', ), 'dashboard-warning' => array( 'label' => 'Warning', 'hint' => 'Warning alerts and caution indicators', 'dark' => '#f59e0b', 'light' => '#f59e0b', ), 'dashboard-error' => array( 'label' => 'Error', 'hint' => 'Error messages and critical alerts', 'dark' => '#ef4444', 'light' => '#ef4444', ), 'dashboard-border' => array( 'label' => 'Border', 'hint' => 'Card borders, dividers, and separators', 'dark' => '#374151', 'light' => '#e5e7eb', ), 'dashboard-gradient-primary-from' => array( 'label' => 'Button Gradient Start', 'hint' => 'Left/top color of buttons, save bars, and active tabs', 'dark' => '#667eea', 'light' => '#667eea', ), 'dashboard-gradient-primary-to' => array( 'label' => 'Button Gradient End', 'hint' => 'Right/bottom color of buttons, save bars, and active tabs', 'dark' => '#764ba2', 'light' => '#764ba2', ), 'dashboard-gradient-accent-from' => array( 'label' => 'Accent Gradient Start', 'hint' => 'Left/top color of secondary badges and highlight bars', 'dark' => '#f093fb', 'light' => '#f093fb', ), 'dashboard-gradient-accent-to' => array( 'label' => 'Accent Gradient End', 'hint' => 'Right/bottom color of secondary badges and highlight bars', 'dark' => '#f5576c', 'light' => '#f5576c', ), ); ?>
$field): ?>

$field): ?>

Export Whitelabel Plugin

Export the entire plugin with all whitelabel settings pre-configured. This creates a complete plugin zip file ready for installation on another WordPress site.

This will create a zip file containing the complete plugin with all your whitelabel settings included. Upload and install this zip file on another WordPress site via Plugins → Add New → Upload Plugin. All whitelabel configurations will be automatically applied upon activation.

'; echo '

Access Denied

'; echo '

You do not have permission to access this page.

'; echo ''; } else { ?>

🧰 Advanced Settings

Technical utilities for troubleshooting and connectivity checks.

render_lock_button('advanced'); ?>
✅ Access Granted: You have successfully authenticated and can now modify settings.

✅ Success! Debug mode has been enabled.

ℹ️ Debug Mode Disabled: Debug mode has been successfully disabled.

✅ Extended! Debug mode has been extended for another 24 hours.

❌ Error: Unable to perform the debug mode operation. Please try again.

admin->render_advanced_accordion(); ?>

✅ Success! All plugin settings have been cleared successfully and a new Plugin Auth Token has been generated. Please reconfigure the plugin as needed.

❌ Error! Failed to clear settings due to a security check failure. Please try again.

✅ Success! Error logs have been cleared successfully.

❌ Error! Failed to clear error logs due to a security check failure. Please try again.

✅ Success! Plugin access roles have been saved successfully.

❌ Error! Failed to save plugin access roles.

admin->render_layout_close(); ?> admin->render_layout_open('Dashboard', 'dashboard', ''); ?>

admin->get_effective_menu_title()); ?> Dashboard

Access your dashboard to view analytics, manage SEO settings, and monitor your site performance.

Authentication required: Please authenticate with your ' . esc_html(Metasync::get_effective_plugin_name()) . ' account and save your auth token in general settings.

'; echo 'Go to Settings'; } else { echo 'Open Dashboard'; } ?>
admin->render_layout_close(); ?> admin->render_layout_open('Robots.txt', 'robots_txt', 'Control which pages search engines can crawl.'); ?> validate_content($content); if ($validation['valid']) { $result = $robots_txt->write_robots_file($content); if (is_wp_error($result)) { echo '

' . esc_html($result->get_error_message()) . '

'; } else { echo '

' . esc_html__('robots.txt file saved successfully!', 'metasync') . '

'; if (!empty($validation['warnings'])) { foreach ($validation['warnings'] as $warning) { echo '

' . esc_html($warning) . '

'; } } } } else { echo '

' . esc_html__('Validation failed. Please fix the errors below:', 'metasync') . '

'; foreach ($validation['errors'] as $error) { echo '

- ' . esc_html($error) . '

'; } echo '
'; } } } $current_content = $robots_txt->read_robots_file(); if (is_wp_error($current_content)) { echo '

' . esc_html($current_content->get_error_message()) . '

'; $current_content = ''; } // First page of backups; the Backup History panel is paginated so the // list always reflects the full stored state and its true total. $backups = $robots_txt->get_backup_history(Metasync_Robots_Txt_Database::BACKUPS_PER_PAGE, 0); $file_exists = $robots_txt->file_exists(); $is_writable = $robots_txt->is_writable(); $robots_txt->render($this->admin, $current_content, $backups, $file_exists, $is_writable); ?> admin->render_layout_close(); ?> admin->render_layout_open('Custom Pages', 'custom_pages', 'Create blank canvas pages for Elementor, Divi, or Gutenberg.'); ?>
admin->render_layout_close(); ?> admin->render_layout_open('404 Monitor', 'monitor_404', 'Track and manage 404 errors detected on your site.'); $ErrorMonitor->create_admin_plugin_interface(); $this->admin->render_layout_close(); } public function create_admin_search_engine_verification_page() { $page_slug = Metasync_Admin::$page_slug . '_searchengines-verification'; ?> admin->render_layout_open('Site Verification', 'site_verification', 'Verify your site ownership with search engines and other platforms.'); ?>

Search Engine Verification

Verify your site ownership with major search engines to access their tools and analytics.

admin->render_layout_close(); ?> admin->render_layout_open('Breadcrumbs', 'breadcrumbs', 'Configure breadcrumb trail settings and placement.'); ?>

Breadcrumbs Settings

Configure how breadcrumb trails are displayed across your site.

render_breadcrumbs_section(); submit_button(); ?>

📖 How to Display Breadcrumbs

Breadcrumbs are not inserted automatically. Use one of the methods below to place them on your site.

Option 1 — Shortcode

Paste the shortcode inside any page, post, or widget:

[metasync_breadcrumb]
Copy

Option 2 — PHP Template Function

Call the helper function directly inside your theme template files (e.g. single.php, page.php, header.php):

<?php metasync_breadcrumb(); ?>
Copy

Option 3 — PHP Return Value

Get the breadcrumb HTML as a string to manipulate before output:

$breadcrumbs = new Metasync_Breadcrumbs();
echo $breadcrumbs->render_breadcrumb_html();
Copy

Tip: You can also pass a post_id argument to generate breadcrumbs for a specific post outside of a template context:
echo $breadcrumbs->render_breadcrumb_html(['post_id' => 123]);

admin->render_layout_close(); ?> admin->render_layout_open('Schema Markup', 'schema_markup', 'Configure global schema markup settings for your site. Organization and WebSite schemas are injected site-wide.'); ?>

Schema Markup Settings

Configure the site-wide Organization and WebSite structured data injected into every page.

admin->render_layout_close(); } public function create_admin_local_business_page() { $page_slug = Metasync_Admin::$page_slug . '_local-seo'; ?> admin->render_layout_open('Local Business', 'local_business', 'Configure local business information for better local SEO.'); ?>

🏢 Local Business Configuration

Configure your local business information for better local search engine optimization.

admin->render_layout_close(); ?> admin->render_layout_open('Code Snippets', 'code_snippets', 'Add custom code to your site header and footer.'); ?>

Code Snippets Management

Add custom code snippets to enhance your site functionality and tracking capabilities.

admin->render_layout_close(); ?> admin->render_layout_open('Google Console', 'google_console', 'View Google Search Console data and manage indexing requests.'); $google = function_exists('google_index_direct') ? google_index_direct() : null; if (is_null($google)) { $service_info = ['error' => 'Module not loaded']; } else { $service_info = $google->get_service_account_info(); } $is_configured = !isset($service_info['error']); include_once plugin_dir_path(dirname(__FILE__)) . 'views/metasync-google-console.php'; $this->admin->render_layout_close(); } public function create_admin_bing_console_page() { ?> admin->render_layout_open('Bing Console', 'bing_console', ''); ?> show_bing_instant_indexing_console(); ?> admin->render_layout_close(); ?> admin->render_layout_open('Global Settings', 'general', ''); ?>

Global Configuration

Configure global settings that apply across your entire site.

admin->render_layout_close(); ?> admin->render_layout_open('Common Meta Settings', 'general', ''); ?>

Meta Configuration

Configure common meta tags and SEO settings for your site.

admin->render_layout_close(); ?> admin->render_layout_open('Social Meta', 'general', ''); ?>

📲 Social Meta Tags

Configure how your content appears when shared on social media platforms.

admin->render_layout_close(); ?> admin->render_layout_open('Indexation Control', 'seo_controls', 'Control how search engines index your content.'); ?>
Import from SEO Plugins
admin->render_layout_close(); ?> admin->render_layout_open('Error Logs', 'general', ''); ?>

Error Logs Management

View and manage system error logs to troubleshoot issues and monitor plugin performance.

can_show_error_logs()) { $log_content = $error_logs->get_error_logs(50); if (!empty(trim($log_content))) { $error_logs->show_copy_button(); $error_logs->show_logs(); $error_logs->show_info(); } else { echo '
'; echo '

✅ Log file is empty - no errors recorded.

'; echo '
'; } } else { $error_message = $error_logs->get_error_message(); if (!empty($error_message)) { echo '
'; echo '

'; echo esc_html($error_message); echo '

'; echo '
'; } else { echo '
'; echo '

Unable to access error log file. Please check permissions.

'; echo '
'; } } ?>
admin->render_layout_close(); ?> Error Logs '); // $error_log = new Metasync_Error_Logs_Table($this->data_error_log_list); // $error_log->create_admin_error_log_list_interface(); } public function create_admin_heartbeat_error_logs_page() { ?> admin->render_layout_open('Heartbeat Error Logs', 'general', ''); ?>

💓 HeartBeat Error Logs

Monitor WordPress heartbeat errors to identify connectivity issues and system problems.

admin->db_heartbeat_errors); $heartbeat_errors->create_admin_heartbeat_errors_interface(); ?>
admin->render_layout_close(); ?>