PluginProbe
Search Atlas SEO – OTTO AI SEO Automation for WordPress / 2.7.1
Search Atlas SEO – OTTO AI SEO Automation for WordPress v2.7.1
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 +47 -18 2.7.2 → 2.7.1 View file →
@@ -262,16 +262,10 @@
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'));
266 267
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 -
274 268 // Add admin_post hooks for form submissions (WordPress standard way - no output buffering needed)
275 269 add_action('admin_post_metasync_clear_all_cache_plugins', array($this, 'handle_clear_all_cache_plugins'));
276 270 add_action('admin_post_metasync_clear_otto_cache_all', array($this, 'handle_clear_otto_cache_all'));
277 271 add_action('admin_post_metasync_clear_otto_cache_url', array($this, 'handle_clear_otto_cache_url'));
@@ -394,8 +388,11 @@
394 388
395 389 # Add AJAX handlers for Bing Instant Indexing (IndexNow)
396 390 add_action('wp_ajax_metasync_send_bing_indexnow', array($this, 'ajax_send_bing_indexnow'));
397 391
392 + # Add hooks for instant indexing settings saves
393 + add_action('admin_init', array($this, 'save_instant_indexing_settings'));
394 +
398 395 # Add hooks for instant indexing post actions
399 396 add_filter('post_row_actions', array($this, 'add_instant_indexing_post_actions'), 10, 2);
400 397 add_filter('page_row_actions', array($this, 'add_instant_indexing_post_actions'), 10, 2);
401 398
@@ -703,8 +700,10 @@
703 700 */
704 701 public function maybe_redirect_to_wizard() {
705 702 // Only redirect if wizard should be shown
706 703 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 +
707 706 // Don't redirect during AJAX, cron, or bulk activation
708 707 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
709 708 return;
710 709 }
@@ -713,9 +712,8 @@
713 712 if (!Metasync::current_user_has_plugin_access()) {
714 713 return;
715 714 }
716 715
717 - delete_option('metasync_show_wizard');
718 716 wp_safe_redirect(admin_url('admin.php?page=' . self::$page_slug . '-setup-wizard'));
719 717 exit;
720 718 }
721 719 }
@@ -725,12 +723,8 @@
725 723 *
726 724 * The menu entry is gone, but bookmarks and external links can still target
727 725 * the old URL. Resolve the current white-label slug rather than assuming
728 726 * "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.
733 727 */
734 728 public function redirect_legacy_instant_indexing_page() {
735 729 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
736 730 return;
@@ -923,11 +917,10 @@
923 917 'all'
924 918 );
925 919 }
926 920
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
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
930 923 wp_enqueue_style(
931 924 $this->plugin_name . '-setup-wizard',
932 925 plugin_dir_url(__FILE__) . 'css/metasync-setup-wizard.css',
933 926 array($this->plugin_name . '-dashboard'),
@@ -3364,9 +3357,9 @@
3364 3357
3365 3358 update_option('metasync_sitemap_settings', $sitemap_settings);
3366 3359
3367 3360 // Regenerate sitemap with new content settings
3368 - $result = $sitemap_generator->generate_sitemap( true );
3361 + $result = $sitemap_generator->generate_sitemap();
3369 3362 if (is_wp_error($result)) {
3370 3363 echo '<div class="notice notice-error"><p>' . esc_html(
3371 3364 /* translators: %s: error message. */
3372 3365 sprintf(__('Settings saved but sitemap generation failed: %s', 'metasync'), $result->get_error_message())
@@ -3520,9 +3513,9 @@
3520 3513 gc_collect_cycles();
3521 3514 }
3522 3515
3523 3516 // Generate main sitemap (its index will include news/video since they now exist)
3524 - $result = $sitemap_generator->generate_sitemap( true );
3517 + $result = $sitemap_generator->generate_sitemap();
3525 3518
3526 3519 if (is_wp_error($result)) {
3527 3520 $error_msg = $result->get_error_message();
3528 3521 error_log('[MetaSync] Sitemap generation failed: ' . $error_msg); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- genuine failure path, bounded, no secrets
@@ -3943,9 +3936,9 @@
3943 3936 {
3944 3937 register_rest_route('metasync/v1', '/ping', array(
3945 3938 'methods' => array('GET', 'POST'),
3946 3939 'callback' => array($this, 'handle_ping_rest_endpoint'),
3947 - 'permission_callback' => '__return_true',
3940 + 'permission_callback' => '__return_true', // Allow public access
3948 3941 'args' => array(
3949 3942 'test' => array(
3950 3943 'description' => 'Optional test parameter',
3951 3944 'type' => 'string',
@@ -6475,8 +6468,44 @@
6475 6468
6476 6469 require_once plugin_dir_path(dirname(__FILE__)) . 'bing-index/class-metasync-bing-instant-index.php';
6477 6470 $bing_instant_index = new Metasync_Bing_Instant_Index();
6478 6471 $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()
6479 6508 }
6480 6509
6481 6510 /**
6482 6511 * Save Bing instant indexing settings from inline form (Indexation Control page)