PluginProbe
Search Atlas SEO – OTTO AI SEO Automation for WordPress / 2.7.2
Search Atlas SEO – OTTO AI SEO Automation for WordPress v2.7.2
2.7.1 2.7.2 2.7.0 2.6.26 2.6.25 2.6.24 2.6.23 2.6.22 2.6.21 2.6.20 2.6.19 2.6.18 2.6.17 2.6.16 2.6.15 2.6.14 2.6.13 2.6.12 2.6.11 2.6.10 2.6.9 2.6.8 2.6.7 2.6.6 2.6.5 All 141 releases
← All changes | admin/class-metasync-admin.php +18 -47 2.7.1 → 2.7.2 View file →
@@ -262,10 +262,16 @@
262 262 add_action('metasync_api_key_changed', array('Metasync_Admin_Navigation', 'invalidate_admin_bar_status_cache'), 10, 0);
263 263
264 264 add_action('admin_init', array($this, 'initialize_cookie'));
265 265 add_action('admin_init', array($this, 'maybe_redirect_to_wizard'));
266 - add_action('admin_init', array($this, 'redirect_legacy_instant_indexing_page'));
267 266
267 + // The redirect must run on admin_menu, not admin_init: in current
268 + // WordPress the unregistered-page access check in wp-admin/includes/
269 + // menu.php fires from wp-admin/menu.php (required at admin.php:163),
270 + // which is BEFORE admin_init (admin.php:180). Hooked on admin_init the
271 + // redirect never ran — WP died with a 403 first for the removed slug.
272 + add_action('admin_menu', array($this, 'redirect_legacy_instant_indexing_page'));
273 +
268 274 // Add admin_post hooks for form submissions (WordPress standard way - no output buffering needed)
269 275 add_action('admin_post_metasync_clear_all_cache_plugins', array($this, 'handle_clear_all_cache_plugins'));
270 276 add_action('admin_post_metasync_clear_otto_cache_all', array($this, 'handle_clear_otto_cache_all'));
271 277 add_action('admin_post_metasync_clear_otto_cache_url', array($this, 'handle_clear_otto_cache_url'));
@@ -388,11 +394,8 @@
388 394
389 395 # Add AJAX handlers for Bing Instant Indexing (IndexNow)
390 396 add_action('wp_ajax_metasync_send_bing_indexnow', array($this, 'ajax_send_bing_indexnow'));
391 397
392 - # Add hooks for instant indexing settings saves
393 - add_action('admin_init', array($this, 'save_instant_indexing_settings'));
394 -
395 398 # Add hooks for instant indexing post actions
396 399 add_filter('post_row_actions', array($this, 'add_instant_indexing_post_actions'), 10, 2);
397 400 add_filter('page_row_actions', array($this, 'add_instant_indexing_post_actions'), 10, 2);
398 401
@@ -700,10 +703,8 @@
700 703 */
701 704 public function maybe_redirect_to_wizard() {
702 705 // Only redirect if wizard should be shown
703 706 if (get_option('metasync_show_wizard') && !isset($_GET['page'])) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- isset() routing check for a redirect to a fixed admin URL
704 - delete_option('metasync_show_wizard');
705 -
706 707 // Don't redirect during AJAX, cron, or bulk activation
707 708 if (wp_doing_ajax() || wp_doing_cron() || isset($_GET['activate-multi'])) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- isset() routing check for a redirect to a fixed admin URL
708 709 return;
709 710 }
@@ -712,8 +713,9 @@
712 713 if (!Metasync::current_user_has_plugin_access()) {
713 714 return;
714 715 }
715 716
717 + delete_option('metasync_show_wizard');
716 718 wp_safe_redirect(admin_url('admin.php?page=' . self::$page_slug . '-setup-wizard'));
717 719 exit;
718 720 }
719 721 }
@@ -723,8 +725,12 @@
723 725 *
724 726 * The menu entry is gone, but bookmarks and external links can still target
725 727 * the old URL. Resolve the current white-label slug rather than assuming
726 728 * "searchatlas".
729 + *
730 + * Hooked on admin_menu (see its registration): the unregistered-page 403 in
731 + * wp-admin/includes/menu.php fires before admin_init, so any later hook
732 + * would be too late to redirect.
727 733 */
728 734 public function redirect_legacy_instant_indexing_page() {
729 735 if (wp_doing_ajax() || wp_doing_cron() || !is_admin() || !isset($_GET['page'])) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only navigation values for a same-site redirect
730 736 return;
@@ -917,10 +923,11 @@
917 923 'all'
918 924 );
919 925 }
920 926
921 - // Enqueue wizard CSS if on wizard page
922 - if (isset($_GET['page']) && strpos(sanitize_key(wp_unslash($_GET['page'])), '-setup-wizard') !== false) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only page check to pick stylesheets
927 + // Enqueue wizard CSS on all MetaSync pages because the reusable consent
928 + // card is also displayed inside General Settings.
929 + if (strpos($current_page, self::$page_slug) === 0 || (isset($_GET['page']) && strpos(sanitize_key(wp_unslash($_GET['page'])), '-setup-wizard') !== false)) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only page check to pick stylesheets
923 930 wp_enqueue_style(
924 931 $this->plugin_name . '-setup-wizard',
925 932 plugin_dir_url(__FILE__) . 'css/metasync-setup-wizard.css',
926 933 array($this->plugin_name . '-dashboard'),
@@ -3357,9 +3364,9 @@
3357 3364
3358 3365 update_option('metasync_sitemap_settings', $sitemap_settings);
3359 3366
3360 3367 // Regenerate sitemap with new content settings
3361 - $result = $sitemap_generator->generate_sitemap();
3368 + $result = $sitemap_generator->generate_sitemap( true );
3362 3369 if (is_wp_error($result)) {
3363 3370 echo '<div class="notice notice-error"><p>' . esc_html(
3364 3371 /* translators: %s: error message. */
3365 3372 sprintf(__('Settings saved but sitemap generation failed: %s', 'metasync'), $result->get_error_message())
@@ -3513,9 +3520,9 @@
3513 3520 gc_collect_cycles();
3514 3521 }
3515 3522
3516 3523 // Generate main sitemap (its index will include news/video since they now exist)
3517 - $result = $sitemap_generator->generate_sitemap();
3524 + $result = $sitemap_generator->generate_sitemap( true );
3518 3525
3519 3526 if (is_wp_error($result)) {
3520 3527 $error_msg = $result->get_error_message();
3521 3528 error_log('[MetaSync] Sitemap generation failed: ' . $error_msg); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- genuine failure path, bounded, no secrets
@@ -3936,9 +3943,9 @@
3936 3943 {
3937 3944 register_rest_route('metasync/v1', '/ping', array(
3938 3945 'methods' => array('GET', 'POST'),
3939 3946 'callback' => array($this, 'handle_ping_rest_endpoint'),
3940 - 'permission_callback' => '__return_true', // Allow public access
3947 + 'permission_callback' => '__return_true',
3941 3948 'args' => array(
3942 3949 'test' => array(
3943 3950 'description' => 'Optional test parameter',
3944 3951 'type' => 'string',
@@ -6468,44 +6475,8 @@
6468 6475
6469 6476 require_once plugin_dir_path(dirname(__FILE__)) . 'bing-index/class-metasync-bing-instant-index.php';
6470 6477 $bing_instant_index = new Metasync_Bing_Instant_Index();
6471 6478 $bing_instant_index->send();
6472 - }
6473 -
6474 - /**
6475 - * Save instant indexing settings (Google and Bing)
6476 - *
6477 - * @since 2.6.0
6478 - * @return void
6479 - */
6480 - public function save_instant_indexing_settings()
6481 - {
6482 - // Check if this is a settings submission
6483 - if (!isset($_POST['submit'])) {
6484 - return;
6485 - }
6486 -
6487 - // This handler runs on admin_init, which also fires inside
6488 - // admin-ajax.php before its login gate, so a bare isset() check let
6489 - // any request (including logged-out ones) rewrite the auto-submit
6490 - // post types. Require the nonce and plugin access before writing.
6491 - if (!isset($_POST['metasync_instant_indexing_nonce'])
6492 - || !wp_verify_nonce(sanitize_key(wp_unslash($_POST['metasync_instant_indexing_nonce'])), 'metasync_instant_indexing_settings')
6493 - || !Metasync::current_user_has_plugin_access()) {
6494 - return;
6495 - }
6496 -
6497 - // Save post types for Google Instant Indexing auto-submit
6498 - if (isset($_POST['metasync_post_types'])) {
6499 - $post_data = metasync_sanitize_input_array($_POST);
6500 - $post_types = is_array($post_data['metasync_post_types']) ? array_map('sanitize_title', $post_data['metasync_post_types']) : [];
6501 -
6502 - $settings = get_option('metasync_options_instant_indexing', ['post_types' => []]);
6503 - $settings['post_types'] = array_values($post_types);
6504 - update_option('metasync_options_instant_indexing', $settings);
6505 - }
6506 -
6507 - // Note: Bing Instant Indexing settings are saved via AJAX in save_bing_inline_settings_ajax()
6508 6479 }
6509 6480
6510 6481 /**
6511 6482 * Save Bing instant indexing settings from inline form (Indexation Control page)