← All changes
|
includes/class-metasync-settings-registration.php
+195
-190
2.7.0
→
2.7.1
View file →
| @@ -180,12 +180,13 @@ | ||
| 180 | 180 | */ |
| 181 | 181 | private function handle_plugin_access_roles_save() |
| 182 | 182 | { |
| 183 | 183 | if (isset($_POST['save_plugin_access_roles']) && $_POST['save_plugin_access_roles'] === 'yes') { |
| 184 | - if (isset($_POST['plugin_access_roles_nonce']) && wp_verify_nonce($_POST['plugin_access_roles_nonce'], 'metasync_plugin_access_roles_nonce')) { | |
| 184 | + $access_roles_nonce = isset($_POST['plugin_access_roles_nonce']) ? sanitize_text_field(wp_unslash($_POST['plugin_access_roles_nonce'])) : ''; | |
| 185 | + if (wp_verify_nonce($access_roles_nonce, 'metasync_plugin_access_roles_nonce')) { | |
| 185 | 186 | |
| 186 | 187 | if (!Metasync::current_user_has_plugin_access()) { |
| 187 | - wp_redirect(admin_url('admin.php?page=' . Metasync_Admin::$page_slug . '&tab=advanced&access_roles_error=1&message=' . urlencode('Insufficient permissions'))); | |
| 188 | + wp_safe_redirect(admin_url('admin.php?page=' . Metasync_Admin::$page_slug . '&tab=advanced&access_roles_error=1&message=' . urlencode('Insufficient permissions'))); | |
| 188 | 189 | exit; |
| 189 | 190 | } |
| 190 | 191 | |
| 191 | 192 | self::$defer_settings_recovery_lock_release = true; |
| @@ -203,9 +204,9 @@ | ||
| 203 | 204 | $metasync_options['general'] = array(); |
| 204 | 205 | } |
| 205 | 206 | |
| 206 | 207 | if (isset($_POST['plugin_access_roles']) && is_array($_POST['plugin_access_roles'])) { |
| 207 | - $metasync_options['general']['plugin_access_roles'] = array_map('sanitize_text_field', $_POST['plugin_access_roles']); | |
| 208 | + $metasync_options['general']['plugin_access_roles'] = array_map('sanitize_text_field', wp_unslash($_POST['plugin_access_roles'])); | |
| 208 | 209 | } else { |
| 209 | 210 | $metasync_options['general']['plugin_access_roles'] = array(); |
| 210 | 211 | } |
| 211 | 212 | |
| @@ -211,13 +212,13 @@ | ||
| 211 | 212 | |
| 212 | 213 | Metasync::set_option($metasync_options); |
| 213 | 214 | |
| 214 | 215 | $redirect_url = admin_url('admin.php?page=' . Metasync_Admin::$page_slug . '&tab=advanced&access_roles_saved=1'); |
| 215 | - wp_redirect($redirect_url); | |
| 216 | + wp_safe_redirect($redirect_url); | |
| 216 | 217 | exit; |
| 217 | 218 | } else { |
| 218 | 219 | $redirect_url = admin_url('admin.php?page=' . Metasync_Admin::$page_slug . '&tab=advanced&access_roles_error=1&message=' . urlencode('Invalid security token')); |
| 219 | - wp_redirect($redirect_url); | |
| 220 | + wp_safe_redirect($redirect_url); | |
| 220 | 221 | exit; |
| 221 | 222 | } |
| 222 | 223 | } |
| 223 | 224 | } |
| @@ -342,9 +343,9 @@ | ||
| 342 | 343 | $value = isset($settings['max_posts']) ? (int) $settings['max_posts'] : 50; |
| 343 | 344 | echo '<div class="llms-txt-dependent">'; |
| 344 | 345 | printf( |
| 345 | 346 | '<input type="number" id="llms_txt_max_posts" name="metasync_llms_txt_settings[max_posts]" min="1" max="500" value="%d" />', |
| 346 | - $value | |
| 347 | + absint($value) | |
| 347 | 348 | ); |
| 348 | 349 | echo '</div>'; |
| 349 | 350 | }, |
| 350 | 351 | $page_slug . '_general', |
| @@ -415,9 +416,9 @@ | ||
| 415 | 416 | $value = isset($settings['max_posts_full']) ? (int) $settings['max_posts_full'] : 25; |
| 416 | 417 | echo '<div class="llms-full-dependent">'; |
| 417 | 418 | printf( |
| 418 | 419 | '<input type="number" id="llms_txt_max_posts_full" name="metasync_llms_txt_settings[max_posts_full]" min="1" max="500" value="%d" />', |
| 419 | - $value | |
| 420 | + absint($value) | |
| 420 | 421 | ); |
| 421 | 422 | echo '<p class="description">' . esc_html__('Maximum posts for /llms-full.txt (lower than summary to protect server performance).', 'metasync') . '</p>'; |
| 422 | 423 | echo '</div>'; |
| 423 | 424 | }, |
| @@ -453,12 +454,12 @@ | ||
| 453 | 454 | 'Disallow Empty Archives', |
| 454 | 455 | function() use ($option_key) { |
| 455 | 456 | $noindex_empty_archives = Metasync::get_option('seo_controls')['noindex_empty_archives'] ?? 'false'; |
| 456 | 457 | printf( |
| 457 | - '<input type="checkbox" id="noindex_empty_archives" name="' . $option_key . '[seo_controls][noindex_empty_archives]" value="true" %s />', | |
| 458 | + '<input type="checkbox" id="noindex_empty_archives" name="' . esc_attr($option_key) . '[seo_controls][noindex_empty_archives]" value="true" %s />', | |
| 458 | 459 | isset($noindex_empty_archives) && $noindex_empty_archives == 'true' ? 'checked' : '' |
| 459 | 460 | ); |
| 460 | - printf('<span class="description"><strong>Empty Archives:</strong> When checked, automatically adds noindex to category, tag, author, and format archive pages that have no posts. Once posts are added to these archives, they will automatically be allowed for indexing. This prevents thin content pages from being indexed.</span>'); | |
| 461 | + echo '<span class="description"><strong>Empty Archives:</strong> When checked, automatically adds noindex to category, tag, author, and format archive pages that have no posts. Once posts are added to these archives, they will automatically be allowed for indexing. This prevents thin content pages from being indexed.</span>'; | |
| 461 | 462 | }, |
| 462 | 463 | $page_slug . '_seo-controls', |
| 463 | 464 | $SECTION_SEO_CONTROLS |
| 464 | 465 | ); |
| @@ -468,12 +469,12 @@ | ||
| 468 | 469 | 'Disallow Date Archives', |
| 469 | 470 | function() use ($option_key) { |
| 470 | 471 | $index_date_archives = Metasync::get_option('seo_controls')['index_date_archives'] ?? 'false'; |
| 471 | 472 | printf( |
| 472 | - '<input type="checkbox" id="index_date_archives" name="' . $option_key . '[seo_controls][index_date_archives]" value="true" %s />', | |
| 473 | + '<input type="checkbox" id="index_date_archives" name="' . esc_attr($option_key) . '[seo_controls][index_date_archives]" value="true" %s />', | |
| 473 | 474 | isset($index_date_archives) && $index_date_archives == 'true' ? 'checked' : '' |
| 474 | 475 | ); |
| 475 | - printf('<span class="description"><strong>Date Archives:</strong> When checked, prevents search engines from indexing date-based archive pages (e.g., /2024/01/, /2024/01/15/). These pages often have thin content and can dilute your site\'s SEO value. Recommended for most sites.</span>'); | |
| 476 | + echo '<span class="description"><strong>Date Archives:</strong> When checked, prevents search engines from indexing date-based archive pages (e.g., /2024/01/, /2024/01/15/). These pages often have thin content and can dilute your site\'s SEO value. Recommended for most sites.</span>'; | |
| 476 | 477 | }, |
| 477 | 478 | $page_slug . '_seo-controls', |
| 478 | 479 | $SECTION_SEO_CONTROLS |
| 479 | 480 | ); |
| @@ -483,12 +484,12 @@ | ||
| 483 | 484 | 'Disallow Tag Archives', |
| 484 | 485 | function() use ($option_key) { |
| 485 | 486 | $index_tag_archives = Metasync::get_option('seo_controls')['index_tag_archives'] ?? 'false'; |
| 486 | 487 | printf( |
| 487 | - '<input type="checkbox" id="index_tag_archives" name="' . $option_key . '[seo_controls][index_tag_archives]" value="true" %s />', | |
| 488 | + '<input type="checkbox" id="index_tag_archives" name="' . esc_attr($option_key) . '[seo_controls][index_tag_archives]" value="true" %s />', | |
| 488 | 489 | isset($index_tag_archives) && $index_tag_archives == 'true' ? 'checked' : '' |
| 489 | 490 | ); |
| 490 | - printf('<span class="description"><strong>Tag Archives:</strong> When checked, prevents search engines from indexing tag archive pages (e.g., /tag/technology/). Useful if you have many low-quality tag pages or want to focus on category-based organization instead.</span>'); | |
| 491 | + echo '<span class="description"><strong>Tag Archives:</strong> When checked, prevents search engines from indexing tag archive pages (e.g., /tag/technology/). Useful if you have many low-quality tag pages or want to focus on category-based organization instead.</span>'; | |
| 491 | 492 | }, |
| 492 | 493 | $page_slug . '_seo-controls', |
| 493 | 494 | $SECTION_SEO_CONTROLS |
| 494 | 495 | ); |
| @@ -498,12 +499,12 @@ | ||
| 498 | 499 | 'Disallow Author Archives', |
| 499 | 500 | function() use ($option_key) { |
| 500 | 501 | $index_author_archives = Metasync::get_option('seo_controls')['index_author_archives'] ?? 'false'; |
| 501 | 502 | printf( |
| 502 | - '<input type="checkbox" id="index_author_archives" name="' . $option_key . '[seo_controls][index_author_archives]" value="true" %s />', | |
| 503 | + '<input type="checkbox" id="index_author_archives" name="' . esc_attr($option_key) . '[seo_controls][index_author_archives]" value="true" %s />', | |
| 503 | 504 | isset($index_author_archives) && $index_author_archives == 'true' ? 'checked' : '' |
| 504 | 505 | ); |
| 505 | - printf('<span class="description"><strong>Author Archives:</strong> When checked, prevents search engines from indexing author archive pages (e.g., /author/john-doe/). Recommended for single-author sites or when author pages don\'t provide unique value. Multi-author sites may want to keep this unchecked.</span>'); | |
| 506 | + echo '<span class="description"><strong>Author Archives:</strong> When checked, prevents search engines from indexing author archive pages (e.g., /author/john-doe/). Recommended for single-author sites or when author pages don\'t provide unique value. Multi-author sites may want to keep this unchecked.</span>'; | |
| 506 | 507 | }, |
| 507 | 508 | $page_slug . '_seo-controls', |
| 508 | 509 | $SECTION_SEO_CONTROLS |
| 509 | 510 | ); |
| @@ -513,12 +514,12 @@ | ||
| 513 | 514 | 'Disallow Format Archives', |
| 514 | 515 | function() use ($option_key) { |
| 515 | 516 | $index_format_archives = Metasync::get_option('seo_controls')['index_format_archives'] ?? 'false'; |
| 516 | 517 | printf( |
| 517 | - '<input type="checkbox" id="index_format_archives" name="' . $option_key . '[seo_controls][index_format_archives]" value="true" %s />', | |
| 518 | + '<input type="checkbox" id="index_format_archives" name="' . esc_attr($option_key) . '[seo_controls][index_format_archives]" value="true" %s />', | |
| 518 | 519 | isset($index_format_archives) && $index_format_archives == 'true' ? 'checked' : '' |
| 519 | 520 | ); |
| 520 | - printf('<span class="description"><strong>Format Archives:</strong> When checked, prevents search engines from indexing post format archive pages (e.g., /type/aside/, /type/gallery/). These are rarely useful for SEO and can create duplicate content issues. Recommended for most sites.</span>'); | |
| 521 | + echo '<span class="description"><strong>Format Archives:</strong> When checked, prevents search engines from indexing post format archive pages (e.g., /type/aside/, /type/gallery/). These are rarely useful for SEO and can create duplicate content issues. Recommended for most sites.</span>'; | |
| 521 | 522 | }, |
| 522 | 523 | $page_slug . '_seo-controls', |
| 523 | 524 | $SECTION_SEO_CONTROLS |
| 524 | 525 | ); |
| @@ -528,12 +529,12 @@ | ||
| 528 | 529 | 'Disallow Category Archives', |
| 529 | 530 | function() use ($option_key) { |
| 530 | 531 | $index_category_archives = Metasync::get_option('seo_controls')['index_category_archives'] ?? 'false'; |
| 531 | 532 | printf( |
| 532 | - '<input type="checkbox" id="index_category_archives" name="' . $option_key . '[seo_controls][index_category_archives]" value="true" %s />', | |
| 533 | + '<input type="checkbox" id="index_category_archives" name="' . esc_attr($option_key) . '[seo_controls][index_category_archives]" value="true" %s />', | |
| 533 | 534 | isset($index_category_archives) && $index_category_archives == 'true' ? 'checked' : '' |
| 534 | 535 | ); |
| 535 | - printf('<span class="description"><strong>Category Archives:</strong> When checked, prevents search engines from indexing category archive pages (e.g., /category/news/). This may be useful if your category pages have thin content or if you want to consolidate SEO value on main pages instead. Use with caution as category pages can be valuable for site organization.</span>'); | |
| 536 | + echo '<span class="description"><strong>Category Archives:</strong> When checked, prevents search engines from indexing category archive pages (e.g., /category/news/). This may be useful if your category pages have thin content or if you want to consolidate SEO value on main pages instead. Use with caution as category pages can be valuable for site organization.</span>'; | |
| 536 | 537 | }, |
| 537 | 538 | $page_slug . '_seo-controls', |
| 538 | 539 | $SECTION_SEO_CONTROLS |
| 539 | 540 | ); |
| @@ -543,9 +544,9 @@ | ||
| 543 | 544 | 'Add No-follow to External Links', |
| 544 | 545 | function() use ($option_key) { |
| 545 | 546 | $add_nofollow_to_external_links = Metasync::get_option('seo_controls')['add_nofollow_to_external_links'] ?? 'false'; |
| 546 | 547 | printf( |
| 547 | - '<input type="checkbox" id="add_nofollow_to_external_links" name="' . $option_key . '[seo_controls][add_nofollow_to_external_links]" value="true" %s />', | |
| 548 | + '<input type="checkbox" id="add_nofollow_to_external_links" name="' . esc_attr($option_key) . '[seo_controls][add_nofollow_to_external_links]" value="true" %s />', | |
| 548 | 549 | isset($add_nofollow_to_external_links) && $add_nofollow_to_external_links == 'true' ? 'checked' : '' |
| 549 | 550 | ); |
| 550 | 551 | printf('<span class="description"><strong>No-follow External Links:</strong> When checked, automatically adds <code>rel="nofollow"</code> attribute to all external links appearing in posts, pages, and other post types when rendered by %s. This tells search engines not to follow these links, which can help preserve your site\'s SEO value and prevent passing link juice to external sites.</span>', esc_html(Metasync::get_whitelabel_otto_name())); |
| 551 | 552 | }, |
| @@ -571,12 +572,12 @@ | ||
| 571 | 572 | 'Override Other Plugins\' Robots Tags', |
| 572 | 573 | function() use ($option_key) { |
| 573 | 574 | $override_robots_tags = Metasync::get_option('seo_controls')['override_robots_tags'] ?? 'false'; |
| 574 | 575 | printf( |
| 575 | - '<input type="checkbox" id="override_robots_tags" name="' . $option_key . '[seo_controls][override_robots_tags]" value="true" %s />', | |
| 576 | + '<input type="checkbox" id="override_robots_tags" name="' . esc_attr($option_key) . '[seo_controls][override_robots_tags]" value="true" %s />', | |
| 576 | 577 | isset($override_robots_tags) && $override_robots_tags == 'true' ? 'checked' : '' |
| 577 | 578 | ); |
| 578 | - printf('<span class="description"><strong>Override Robots Tags:</strong> When checked, ' . Metasync_Settings_Registration::instance()->get_effective_menu_title() . ' will take precedence over robots meta tags from other SEO plugins (Yoast, Rank Math, All in One SEO, etc.). This removes their noindex tags when you want to allow indexing on archive pages. Only enable this if other plugins are conflicting with your indexation settings.</span>'); | |
| 579 | + echo '<span class="description"><strong>Override Robots Tags:</strong> When checked, ' . esc_html(Metasync_Settings_Registration::instance()->get_effective_menu_title()) . ' will take precedence over robots meta tags from other SEO plugins (Yoast, Rank Math, All in One SEO, etc.). This removes their noindex tags when you want to allow indexing on archive pages. Only enable this if other plugins are conflicting with your indexation settings.</span>'; | |
| 579 | 580 | }, |
| 580 | 581 | $page_slug . '_seo-controls', |
| 581 | 582 | $SECTION_SEO_CONTROLS_ADVANCED |
| 582 | 583 | ); |
| @@ -599,13 +600,13 @@ | ||
| 599 | 600 | 'Enable Google Instant Indexing', |
| 600 | 601 | function() use ($option_key) { |
| 601 | 602 | $enable_googleinstantindex = Metasync::get_option('seo_controls')['enable_googleinstantindex'] ?? 'false'; |
| 602 | 603 | printf( |
| 603 | - '<input type="checkbox" id="enable_googleinstantindex" name="' . $option_key . '[seo_controls][enable_googleinstantindex]" value="true" %s />', | |
| 604 | + '<input type="checkbox" id="enable_googleinstantindex" name="' . esc_attr($option_key) . '[seo_controls][enable_googleinstantindex]" value="true" %s />', | |
| 604 | 605 | isset($enable_googleinstantindex) && $enable_googleinstantindex == 'true' ? 'checked' : '' |
| 605 | 606 | ); |
| 606 | 607 | Metasync::render_tooltip_icon('enable_googleinstantindex', 'Turns on direct URL submission to Google. It only works after you add a service-account key below and verify your site in Search Console — set those up first.'); |
| 607 | - printf('<span class="description" style="margin-left:8px;"><strong>Enable Instant Indexing:</strong> When checked, enables the Google Instant Indexing feature which allows you to submit URLs directly to Google for faster indexing. Configure it in the Google Instant Indexing section below.</span>'); | |
| 608 | + echo '<span class="description" style="margin-left:8px;"><strong>Enable Instant Indexing:</strong> When checked, enables the Google Instant Indexing feature which allows you to submit URLs directly to Google for faster indexing. Configure it in the Google Instant Indexing section below.</span>'; | |
| 608 | 609 | }, |
| 609 | 610 | $page_slug . '_seo-controls', |
| 610 | 611 | $SECTION_SEO_CONTROLS_INSTANT_INDEX |
| 611 | 612 | ); |
| @@ -646,13 +647,13 @@ | ||
| 646 | 647 | $enable_binginstantindex = 'true'; |
| 647 | 648 | } |
| 648 | 649 | |
| 649 | 650 | printf( |
| 650 | - '<input type="checkbox" id="enable_binginstantindex" name="' . $option_key . '[seo_controls][enable_binginstantindex]" value="true" %s %s />', | |
| 651 | + '<input type="checkbox" id="enable_binginstantindex" name="' . esc_attr($option_key) . '[seo_controls][enable_binginstantindex]" value="true" %s %s />', | |
| 651 | 652 | isset($enable_binginstantindex) && $enable_binginstantindex == 'true' ? 'checked' : '', |
| 652 | 653 | $has_api_key ? 'data-auto-enabled="true"' : '' |
| 653 | 654 | ); |
| 654 | - printf('<span class="description"><strong>Enable Bing Instant Indexing:</strong> Automatically enabled when you configure an API key below. When enabled, this activates the IndexNow protocol to instantly notify Bing, Yandex, and other search engines about URL changes.</span>'); | |
| 655 | + echo '<span class="description"><strong>Enable Bing Instant Indexing:</strong> Automatically enabled when you configure an API key below. When enabled, this activates the IndexNow protocol to instantly notify Bing, Yandex, and other search engines about URL changes.</span>'; | |
| 655 | 656 | }, |
| 656 | 657 | $page_slug . '_seo-controls', |
| 657 | 658 | 'seo_controls_bing_instant_index' |
| 658 | 659 | ); |
| @@ -693,9 +694,9 @@ | ||
| 693 | 694 | 'otto_pixel_uuid', |
| 694 | 695 | $whitelabel_otto_name . ' Pixel UUID', |
| 695 | 696 | function() use ($option_key) { |
| 696 | 697 | $value = Metasync::get_option('general')['otto_pixel_uuid'] ?? ''; |
| 697 | - printf('<input type="text" size="40" value = "'.esc_attr($value).'" name="' . $option_key . '[general][otto_pixel_uuid]"/>'); | |
| 698 | + echo '<input type="text" size="40" value = "'.esc_attr($value).'" name="' . esc_attr($option_key) . '[general][otto_pixel_uuid]"/>'; | |
| 698 | 699 | }, |
| 699 | 700 | $page_slug . '_general', |
| 700 | 701 | $SECTION_METASYNC |
| 701 | 702 | ); |
| @@ -707,12 +708,12 @@ | ||
| 707 | 708 | 'Disable ' . $whitelabel_otto_name . ' for Logged in Users', |
| 708 | 709 | function() use ($whitelabel_otto_name, $option_key) { |
| 709 | 710 | $otto_disable_on_loggedin = Metasync::get_option('general')['otto_disable_on_loggedin'] ?? ''; |
| 710 | 711 | printf( |
| 711 | - '<input type="checkbox" id="otto_disable_on_loggedin" name="' . $option_key . '[general][otto_disable_on_loggedin]" value="true" %s />', | |
| 712 | + '<input type="checkbox" id="otto_disable_on_loggedin" name="' . esc_attr($option_key) . '[general][otto_disable_on_loggedin]" value="true" %s />', | |
| 712 | 713 | isset($otto_disable_on_loggedin) && $otto_disable_on_loggedin == 'true' ? 'checked' : '' |
| 713 | 714 | ); |
| 714 | - printf('<span class="description"> This disables '.$whitelabel_otto_name.' when logged in to allow editing original page contents</span>'); | |
| 715 | + echo '<span class="description"> This disables '.esc_html($whitelabel_otto_name).' when logged in to allow editing original page contents</span>'; | |
| 715 | 716 | }, |
| 716 | 717 | $page_slug . '_general', |
| 717 | 718 | $SECTION_METASYNC |
| 718 | 719 | ); |
| @@ -723,9 +724,9 @@ | ||
| 723 | 724 | 'Disable ' . $whitelabel_otto_name . ' Frontend Toolbar', |
| 724 | 725 | function() use ($whitelabel_otto_name, $option_key) { |
| 725 | 726 | $otto_disable_toolbar = Metasync::get_option('general')['otto_disable_preview_button'] ?? false; |
| 726 | 727 | printf( |
| 727 | - '<input type="checkbox" id="otto_disable_preview_button" name="' . $option_key . '[general][otto_disable_preview_button]" value="true" %s />', | |
| 728 | + '<input type="checkbox" id="otto_disable_preview_button" name="' . esc_attr($option_key) . '[general][otto_disable_preview_button]" value="true" %s />', | |
| 728 | 729 | filter_var($otto_disable_toolbar, FILTER_VALIDATE_BOOLEAN) ? 'checked' : '' |
| 729 | 730 | ); |
| 730 | 731 | printf('<span class="description"> Hide the entire frontend toolbar (status indicator, preview button, and debug button) on the frontend. %s functionality will still work, but the toolbar controls will be hidden.</span>', esc_html($whitelabel_otto_name)); |
| 731 | 732 | }, |
| @@ -744,19 +745,19 @@ | ||
| 744 | 745 | # from the stored post meta, so unchecking it restores the custom value |
| 745 | 746 | # untouched. Applies to the SEO title and meta description only. |
| 746 | 747 | add_settings_field( |
| 747 | 748 | 'seo_priority', |
| 748 | - 'SEO Title & Description Priority', | |
| 749 | + 'SEO Title & Description Priority', | |
| 749 | 750 | function() use ($whitelabel_otto_name, $option_key) { |
| 750 | 751 | $seo_priority = Metasync::get_option('general')['seo_priority'] ?? ''; |
| 751 | 752 | $checked = $seo_priority === Metasync_Seo_Precedence::PRIORITY_OTTO ? 'checked' : ''; |
| 752 | - $name = esc_attr($option_key) . '[general][seo_priority]'; | |
| 753 | + $name = $option_key . '[general][seo_priority]'; | |
| 753 | 754 | |
| 754 | 755 | echo '<div class="metasync-seo-priority-control">'; |
| 755 | 756 | printf( |
| 756 | 757 | '<label for="seo_priority"><input type="checkbox" id="seo_priority" name="%s" value="otto" %s /> <strong>Prioritize approved %s values</strong></label>', |
| 757 | - $name, | |
| 758 | - $checked, | |
| 758 | + esc_attr($name), | |
| 759 | + esc_attr($checked), | |
| 759 | 760 | esc_html($whitelabel_otto_name) |
| 760 | 761 | ); |
| 761 | 762 | printf( |
| 762 | 763 | '<p class="description" id="seo_priority_description"><strong>Off:</strong> Your custom title and description appear first; %1$s fills in only where you have no value.<br><strong>On:</strong> Approved %1$s values appear first; your custom values remain the fallback.<br><span class="metasync-seo-priority-note">Your saved values are never deleted or overwritten.</span></p>', |
| @@ -775,9 +776,9 @@ | ||
| 775 | 776 | function() use ($whitelabel_otto_name, $option_key) { |
| 776 | 777 | $value = Metasync::get_option('general')['otto_wp_rocket_compat'] ?? 'auto'; |
| 777 | 778 | $wp_rocket_active = class_exists('WP_Rocket'); |
| 778 | 779 | |
| 779 | - echo '<select id="otto_wp_rocket_compat" name="' . $option_key . '[general][otto_wp_rocket_compat]">'; | |
| 780 | + echo '<select id="otto_wp_rocket_compat" name="' . esc_attr($option_key) . '[general][otto_wp_rocket_compat]">'; | |
| 780 | 781 | echo '<option value="auto"' . selected($value, 'auto', false) . '>Auto (Recommended)</option>'; |
| 781 | 782 | echo '<option value="buffer"' . selected($value, 'buffer', false) . '>Buffer Mode (Faster)</option>'; |
| 782 | 783 | echo '<option value="http"' . selected($value, 'http', false) . '>HTTP Mode (Safer)</option>'; |
| 783 | 784 | echo '<option value="disable_otto"' . selected($value, 'disable_otto', false) . '>Disable ' . esc_html($whitelabel_otto_name) . ' when WP Rocket is active</option>'; |
| @@ -805,9 +806,9 @@ | ||
| 805 | 806 | function() use ($option_key) { |
| 806 | 807 | $value = Metasync::get_option('general')['otto_sg_optimizer_compat'] ?? 'auto'; |
| 807 | 808 | $sg_optimizer_active = defined('SiteGround_Optimizer\VERSION') || class_exists('SiteGround_Optimizer\Parser\Parser'); |
| 808 | 809 | |
| 809 | - echo '<select id="otto_sg_optimizer_compat" name="' . $option_key . '[general][otto_sg_optimizer_compat]">'; | |
| 810 | + echo '<select id="otto_sg_optimizer_compat" name="' . esc_attr($option_key) . '[general][otto_sg_optimizer_compat]">'; | |
| 810 | 811 | echo '<option value="auto"' . selected($value, 'auto', false) . '>Auto (Recommended)</option>'; |
| 811 | 812 | echo '<option value="buffer"' . selected($value, 'buffer', false) . '>Buffer Mode (Faster)</option>'; |
| 812 | 813 | echo '<option value="http"' . selected($value, 'http', false) . '>HTTP Mode (Safer)</option>'; |
| 813 | 814 | echo '</select>'; |
| @@ -837,9 +838,9 @@ | ||
| 837 | 838 | 'BookingPress Session Compatibility', |
| 838 | 839 | function() use ($option_key) { |
| 839 | 840 | $value = Metasync::get_option('general')['bookingpress_session_compat'] ?? 'auto'; |
| 840 | 841 | |
| 841 | - echo '<select id="bookingpress_session_compat" name="' . $option_key . '[general][bookingpress_session_compat]">'; | |
| 842 | + echo '<select id="bookingpress_session_compat" name="' . esc_attr($option_key) . '[general][bookingpress_session_compat]">'; | |
| 842 | 843 | echo '<option value="auto"' . selected($value, 'auto', false) . '>Auto (Recommended)</option>'; |
| 843 | 844 | echo '<option value="off"' . selected($value, 'off', false) . '>Disabled</option>'; |
| 844 | 845 | echo '</select>'; |
| 845 | 846 | |
| @@ -867,9 +868,9 @@ | ||
| 867 | 868 | 'Disable ' . $whitelabel_otto_name . ' for Bot Traffic', |
| 868 | 869 | function() use ($whitelabel_otto_name, $option_key) { |
| 869 | 870 | $otto_disable_for_bots = Metasync::get_option('general')['otto_disable_for_bots'] ?? false; |
| 870 | 871 | printf( |
| 871 | - '<input type="checkbox" id="otto_disable_for_bots" name="' . $option_key . '[general][otto_disable_for_bots]" value="true" %s />', | |
| 872 | + '<input type="checkbox" id="otto_disable_for_bots" name="' . esc_attr($option_key) . '[general][otto_disable_for_bots]" value="true" %s />', | |
| 872 | 873 | filter_var($otto_disable_for_bots, FILTER_VALIDATE_BOOLEAN) ? 'checked' : '' |
| 873 | 874 | ); |
| 874 | 875 | printf('<span class="description"> Skip %s processing for detected bots (search engines, crawlers, SEO tools) to reduce unnecessary API calls. View bot statistics in the Bot Statistics page under the SEO dropdown.</span>', esc_html($whitelabel_otto_name)); |
| 875 | 876 | }, |
| @@ -883,9 +884,9 @@ | ||
| 883 | 884 | 'Bot Whitelist', |
| 884 | 885 | function() use ($whitelabel_otto_name, $option_key) { |
| 885 | 886 | $otto_bot_whitelist = Metasync::get_option('general')['otto_bot_whitelist'] ?? ''; |
| 886 | 887 | printf( |
| 887 | - '<textarea id="otto_bot_whitelist" name="' . $option_key . '[general][otto_bot_whitelist]" rows="5" cols="50" style="width: 100%%; max-width: 500px; font-family: monospace;">%s</textarea>', | |
| 888 | + '<textarea id="otto_bot_whitelist" name="' . esc_attr($option_key) . '[general][otto_bot_whitelist]" rows="5" cols="50" style="width: 100%%; max-width: 500px; font-family: monospace;">%s</textarea>', | |
| 888 | 889 | esc_textarea($otto_bot_whitelist) |
| 889 | 890 | ); |
| 890 | 891 | echo '<p class="description">'; |
| 891 | 892 | echo 'Enter bot names or user-agent patterns (one per line) that should <strong>always</strong> be processed by ' . esc_html($whitelabel_otto_name) . ', even when "Disable for Bots" is enabled.<br>'; |
| @@ -904,9 +905,9 @@ | ||
| 904 | 905 | 'Bot Blacklist', |
| 905 | 906 | function() use ($whitelabel_otto_name, $option_key) { |
| 906 | 907 | $otto_bot_blacklist = Metasync::get_option('general')['otto_bot_blacklist'] ?? ''; |
| 907 | 908 | printf( |
| 908 | - '<textarea id="otto_bot_blacklist" name="' . $option_key . '[general][otto_bot_blacklist]" rows="5" cols="50" style="width: 100%%; max-width: 500px; font-family: monospace;">%s</textarea>', | |
| 909 | + '<textarea id="otto_bot_blacklist" name="' . esc_attr($option_key) . '[general][otto_bot_blacklist]" rows="5" cols="50" style="width: 100%%; max-width: 500px; font-family: monospace;">%s</textarea>', | |
| 909 | 910 | esc_textarea($otto_bot_blacklist) |
| 910 | 911 | ); |
| 911 | 912 | echo '<p class="description">'; |
| 912 | 913 | echo 'Enter bot names or user-agent patterns (one per line) that should <strong>always</strong> be blocked from ' . esc_html($whitelabel_otto_name) . ' processing, regardless of other settings.<br>'; |
| @@ -928,9 +929,9 @@ | ||
| 928 | 929 | printf( |
| 929 | 930 | '<a href="%s" class="button button-secondary"><span class="dashicons dashicons-chart-bar" style="margin-top:3px;font-size:15px;width:15px;height:15px;"></span> View Bot Statistics</a>', |
| 930 | 931 | esc_url(admin_url('admin.php?page=' . $page_slug . '-bot-statistics')) |
| 931 | 932 | ); |
| 932 | - printf('<p class="description">View detailed bot detection statistics, breakdown by bot type, and unique bot entries with hit counts.</p>'); | |
| 933 | + echo '<p class="description">View detailed bot detection statistics, breakdown by bot type, and unique bot entries with hit counts.</p>'; | |
| 933 | 934 | }, |
| 934 | 935 | $page_slug . '_general', |
| 935 | 936 | $SECTION_METASYNC |
| 936 | 937 | ); |
| @@ -941,22 +942,20 @@ | ||
| 941 | 942 | 'periodic_clear_ottopage_cache', |
| 942 | 943 | 'Clear Page Cache', |
| 943 | 944 | function() use ($option_key) { |
| 944 | 945 | $periodic_clear_ottopage_cache = Metasync::get_option('general')['periodic_clear_ottopage_cache'] ?? 'default'; |
| 945 | - printf('<select style = "width : 250px" name="' . $option_key . '[general][periodic_clear_ottopage_cache]" id="heading_style">'); | |
| 946 | - printf('<option value="24" '. selected($periodic_clear_ottopage_cache, '24', false) . '>Clear Daily</option>'); | |
| 947 | - printf('<option value="36" '. selected($periodic_clear_ottopage_cache, '36', false) . '>Clear Every 2 days</option>'); | |
| 948 | - printf('<option value="40" '. selected($periodic_clear_ottopage_cache, '40', false) . '>Clear Weekly</option>'); | |
| 949 | - printf('<option value="0"'.selected($periodic_clear_ottopage_cache, '0', false).'>Clear Monthly (Default)</option>'); | |
| 950 | - printf('</select>'); | |
| 946 | + echo '<select style = "width : 250px" name="' . esc_attr($option_key) . '[general][periodic_clear_ottopage_cache]" id="heading_style">'; | |
| 947 | + echo '<option value="24" '. selected($periodic_clear_ottopage_cache, '24', false) . '>Clear Daily</option>'; | |
| 948 | + echo '<option value="36" '. selected($periodic_clear_ottopage_cache, '36', false) . '>Clear Every 2 days</option>'; | |
| 949 | + echo '<option value="40" '. selected($periodic_clear_ottopage_cache, '40', false) . '>Clear Weekly</option>'; | |
| 950 | + echo '<option value="0"'.selected($periodic_clear_ottopage_cache, '0', false).'>Clear Monthly (Default)</option>'; | |
| 951 | + echo '</select>'; | |
| 951 | 952 | |
| 952 | 953 | # get last cleared timestamp |
| 953 | 954 | $timestamp = get_option('metasync_refresh_all_caches')['pages'] ?? false; |
| 954 | 955 | |
| 955 | 956 | if($timestamp > 0){ |
| 956 | - printf( | |
| 957 | - '<p class="descriptionValue">last Cleared : '.date('y-m-d H:i:s', $timestamp).'</p>' | |
| 958 | - ); | |
| 957 | + echo '<p class="descriptionValue">last Cleared : '.esc_html(gmdate('y-m-d H:i:s', $timestamp)).'</p>'; | |
| 959 | 958 | } |
| 960 | 959 | |
| 961 | 960 | }, |
| 962 | 961 | $page_slug . '_otto_cache', |
| @@ -967,22 +966,20 @@ | ||
| 967 | 966 | 'periodic_clear_ottopost_cache', |
| 968 | 967 | 'Clear Post Cache', |
| 969 | 968 | function() use ($option_key) { |
| 970 | 969 | $periodic_clear_ottopost_cache = Metasync::get_option('general')['periodic_clear_ottopost_cache'] ?? 'default'; |
| 971 | - printf('<select style = "width : 250px" name="' . $option_key . '[general][periodic_clear_ottopost_cache]" id="heading_style">'); | |
| 972 | - printf('<option value="24" '. selected($periodic_clear_ottopost_cache, '24', false) . '>Clear Daily</option>'); | |
| 973 | - printf('<option value="36" '. selected($periodic_clear_ottopost_cache, '36', false) . '>Clear Every 2 days</option>'); | |
| 974 | - printf('<option value="40" '. selected($periodic_clear_ottopost_cache, '40', false) . '>Clear Weekly</option>'); | |
| 975 | - printf('<option value="0"'.selected($periodic_clear_ottopost_cache, '0', false).'>Clear Monthly (Default)</option>'); | |
| 976 | - printf('</select>'); | |
| 970 | + echo '<select style = "width : 250px" name="' . esc_attr($option_key) . '[general][periodic_clear_ottopost_cache]" id="heading_style">'; | |
| 971 | + echo '<option value="24" '. selected($periodic_clear_ottopost_cache, '24', false) . '>Clear Daily</option>'; | |
| 972 | + echo '<option value="36" '. selected($periodic_clear_ottopost_cache, '36', false) . '>Clear Every 2 days</option>'; | |
| 973 | + echo '<option value="40" '. selected($periodic_clear_ottopost_cache, '40', false) . '>Clear Weekly</option>'; | |
| 974 | + echo '<option value="0"'.selected($periodic_clear_ottopost_cache, '0', false).'>Clear Monthly (Default)</option>'; | |
| 975 | + echo '</select>'; | |
| 977 | 976 | |
| 978 | 977 | # get last cleared timestamp |
| 979 | 978 | $timestamp = get_option('metasync_refresh_all_caches')['posts'] ?? false; |
| 980 | 979 | |
| 981 | 980 | if($timestamp > 0){ |
| 982 | - printf( | |
| 983 | - '<p class="descriptionValue">last Cleared : '.date('y-m-d H:i:s', $timestamp).'</p>' | |
| 984 | - ); | |
| 981 | + echo '<p class="descriptionValue">last Cleared : '.esc_html(gmdate('y-m-d H:i:s', $timestamp)).'</p>'; | |
| 985 | 982 | } |
| 986 | 983 | }, |
| 987 | 984 | $page_slug . '_otto_cache', |
| 988 | 985 | $SECTION_METASYNC |
| @@ -992,22 +989,20 @@ | ||
| 992 | 989 | 'periodic_clear_otto_cache', |
| 993 | 990 | 'Clear all cache', |
| 994 | 991 | function() use ($option_key) { |
| 995 | 992 | $periodic_clear_otto_cache = Metasync::get_option('general')['periodic_clear_otto_cache'] ?? 'default'; |
| 996 | - printf('<select style = "width : 250px" name="' . $option_key . '[general][periodic_clear_otto_cache]" id="heading_style">'); | |
| 997 | - printf('<option value="24" '. selected($periodic_clear_otto_cache, '24', false) . '>Clear Daily</option>'); | |
| 998 | - printf('<option value="36" '. selected($periodic_clear_otto_cache, '36', false) . '>Clear Every 2 days</option>'); | |
| 999 | - printf('<option value="40" '. selected($periodic_clear_otto_cache, '40', false) . '>Clear Weekly</option>'); | |
| 1000 | - printf('<option value="0"'.selected($periodic_clear_otto_cache, '0', false).'>Clear Monthly (Default)</option>'); | |
| 1001 | - printf('</select>'); | |
| 993 | + echo '<select style = "width : 250px" name="' . esc_attr($option_key) . '[general][periodic_clear_otto_cache]" id="heading_style">'; | |
| 994 | + echo '<option value="24" '. selected($periodic_clear_otto_cache, '24', false) . '>Clear Daily</option>'; | |
| 995 | + echo '<option value="36" '. selected($periodic_clear_otto_cache, '36', false) . '>Clear Every 2 days</option>'; | |
| 996 | + echo '<option value="40" '. selected($periodic_clear_otto_cache, '40', false) . '>Clear Weekly</option>'; | |
| 997 | + echo '<option value="0"'.selected($periodic_clear_otto_cache, '0', false).'>Clear Monthly (Default)</option>'; | |
| 998 | + echo '</select>'; | |
| 1002 | 999 | |
| 1003 | 1000 | # get last cleared timestamp |
| 1004 | 1001 | $timestamp = get_option('metasync_refresh_all_caches')['general'] ?? false; |
| 1005 | 1002 | |
| 1006 | 1003 | if($timestamp > 0){ |
| 1007 | - printf( | |
| 1008 | - '<p class="descriptionValue">last Cleared : '.date('y-m-d H:i:s', $timestamp).'</p>' | |
| 1009 | - ); | |
| 1004 | + echo '<p class="descriptionValue">last Cleared : '.esc_html(gmdate('y-m-d H:i:s', $timestamp)).'</p>'; | |
| 1010 | 1005 | } |
| 1011 | 1006 | |
| 1012 | 1007 | }, |
| 1013 | 1008 | $page_slug . '_otto_cache', |
| @@ -1022,12 +1017,12 @@ | ||
| 1022 | 1017 | 'Disable Common Robots Meta Box', |
| 1023 | 1018 | function() use ($option_key) { |
| 1024 | 1019 | $disabled = Metasync::get_option('general')['disable_common_robots_metabox'] ?? false; |
| 1025 | 1020 | printf( |
| 1026 | - '<input type="checkbox" id="disable_common_robots_metabox" name="' . $option_key . '[general][disable_common_robots_metabox]" value="1" %s />', | |
| 1021 | + '<input type="checkbox" id="disable_common_robots_metabox" name="' . esc_attr($option_key) . '[general][disable_common_robots_metabox]" value="1" %s />', | |
| 1027 | 1022 | $disabled ? 'checked' : '' |
| 1028 | 1023 | ); |
| 1029 | - printf('<span class="description"> Hide the Common Robots meta box and stop %1$s emitting index/follow robots directives on the front end. While disabled, %1$s does not manage or override this data — another SEO plugin, or none, is free to handle it. Saved values are kept.</span>', Metasync::get_effective_plugin_name('MetaSync')); | |
| 1024 | + printf('<span class="description"> Hide the Common Robots meta box and stop %1$s emitting index/follow robots directives on the front end. While disabled, %1$s does not manage or override this data — another SEO plugin, or none, is free to handle it. Saved values are kept.</span>', esc_html(Metasync::get_effective_plugin_name('MetaSync'))); | |
| 1030 | 1025 | }, |
| 1031 | 1026 | $page_slug . '_general', |
| 1032 | 1027 | $SECTION_METASYNC |
| 1033 | 1028 | ); |
| @@ -1037,12 +1032,12 @@ | ||
| 1037 | 1032 | 'Disable Advance Robots Meta Box', |
| 1038 | 1033 | function() use ($option_key) { |
| 1039 | 1034 | $disabled = Metasync::get_option('general')['disable_advance_robots_metabox'] ?? false; |
| 1040 | 1035 | printf( |
| 1041 | - '<input type="checkbox" id="disable_advance_robots_metabox" name="' . $option_key . '[general][disable_advance_robots_metabox]" value="1" %s />', | |
| 1036 | + '<input type="checkbox" id="disable_advance_robots_metabox" name="' . esc_attr($option_key) . '[general][disable_advance_robots_metabox]" value="1" %s />', | |
| 1042 | 1037 | $disabled ? 'checked' : '' |
| 1043 | 1038 | ); |
| 1044 | - printf('<span class="description"> Hide the Advance Robots meta box and stop %1$s emitting max-snippet, max-image-preview and max-video-preview directives. While disabled, %1$s does not manage or override this data — another SEO plugin, or none, is free to handle it. Saved values are kept.</span>', Metasync::get_effective_plugin_name('MetaSync')); | |
| 1039 | + printf('<span class="description"> Hide the Advance Robots meta box and stop %1$s emitting max-snippet, max-image-preview and max-video-preview directives. While disabled, %1$s does not manage or override this data — another SEO plugin, or none, is free to handle it. Saved values are kept.</span>', esc_html(Metasync::get_effective_plugin_name('MetaSync'))); | |
| 1045 | 1040 | }, |
| 1046 | 1041 | $page_slug . '_general', |
| 1047 | 1042 | $SECTION_METASYNC |
| 1048 | 1043 | ); |
| @@ -1052,12 +1047,12 @@ | ||
| 1052 | 1047 | 'Disable Redirection Meta Box', |
| 1053 | 1048 | function() use ($option_key) { |
| 1054 | 1049 | $disabled = Metasync::get_option('general')['disable_redirection_metabox'] ?? false; |
| 1055 | 1050 | printf( |
| 1056 | - '<input type="checkbox" id="disable_redirection_metabox" name="' . $option_key . '[general][disable_redirection_metabox]" value="1" %s />', | |
| 1051 | + '<input type="checkbox" id="disable_redirection_metabox" name="' . esc_attr($option_key) . '[general][disable_redirection_metabox]" value="1" %s />', | |
| 1057 | 1052 | $disabled ? 'checked' : '' |
| 1058 | 1053 | ); |
| 1059 | - printf('<span class="description"> Hide the Redirection meta box and stop redirects created by it from running. Rules added on the Redirections screen are unaffected. Saved redirects are kept.</span>'); | |
| 1054 | + echo '<span class="description"> Hide the Redirection meta box and stop redirects created by it from running. Rules added on the Redirections screen are unaffected. Saved redirects are kept.</span>'; | |
| 1060 | 1055 | }, |
| 1061 | 1056 | $page_slug . '_general', |
| 1062 | 1057 | $SECTION_METASYNC |
| 1063 | 1058 | ); |
| @@ -1067,12 +1062,12 @@ | ||
| 1067 | 1062 | 'Disable Canonical Meta Box', |
| 1068 | 1063 | function() use ($option_key) { |
| 1069 | 1064 | $disabled = Metasync::get_option('general')['disable_canonical_metabox'] ?? false; |
| 1070 | 1065 | printf( |
| 1071 | - '<input type="checkbox" id="disable_canonical_metabox" name="' . $option_key . '[general][disable_canonical_metabox]" value="1" %s />', | |
| 1066 | + '<input type="checkbox" id="disable_canonical_metabox" name="' . esc_attr($option_key) . '[general][disable_canonical_metabox]" value="1" %s />', | |
| 1072 | 1067 | $disabled ? 'checked' : '' |
| 1073 | 1068 | ); |
| 1074 | - printf('<span class="description"> Hide the Canonical meta box and stop %1$s emitting or overriding the canonical URL. While disabled, %1$s does not manage or override this data — another SEO plugin, or none, is free to handle it. Saved values are kept.</span>', Metasync::get_effective_plugin_name('MetaSync')); | |
| 1069 | + printf('<span class="description"> Hide the Canonical meta box and stop %1$s emitting or overriding the canonical URL. While disabled, %1$s does not manage or override this data — another SEO plugin, or none, is free to handle it. Saved values are kept.</span>', esc_html(Metasync::get_effective_plugin_name('MetaSync'))); | |
| 1075 | 1070 | }, |
| 1076 | 1071 | $page_slug . '_general', |
| 1077 | 1072 | $SECTION_METASYNC |
| 1078 | 1073 | ); |
| @@ -1082,12 +1077,12 @@ | ||
| 1082 | 1077 | 'Disable Social Media & Open Graph Meta Box', |
| 1083 | 1078 | function() use ($option_key) { |
| 1084 | 1079 | $disabled = Metasync::get_option('general')['disable_social_opengraph_metabox'] ?? false; |
| 1085 | 1080 | printf( |
| 1086 | - '<input type="checkbox" id="disable_social_opengraph_metabox" name="' . $option_key . '[general][disable_social_opengraph_metabox]" value="1" %s />', | |
| 1081 | + '<input type="checkbox" id="disable_social_opengraph_metabox" name="' . esc_attr($option_key) . '[general][disable_social_opengraph_metabox]" value="1" %s />', | |
| 1087 | 1082 | $disabled ? 'checked' : '' |
| 1088 | 1083 | ); |
| 1089 | - printf('<span class="description"> Hide the Social Media & Open Graph meta box and stop %1$s emitting Open Graph and Twitter tags. While disabled, %1$s does not manage or override this data — another SEO plugin, or none, is free to handle it. Saved values are kept.</span>', Metasync::get_effective_plugin_name('MetaSync')); | |
| 1084 | + printf('<span class="description"> Hide the Social Media & Open Graph meta box and stop %1$s emitting Open Graph and Twitter tags. While disabled, %1$s does not manage or override this data — another SEO plugin, or none, is free to handle it. Saved values are kept.</span>', esc_html(Metasync::get_effective_plugin_name('MetaSync'))); | |
| 1090 | 1085 | }, |
| 1091 | 1086 | $page_slug . '_general', |
| 1092 | 1087 | $SECTION_METASYNC |
| 1093 | 1088 | ); |
| @@ -1097,12 +1092,12 @@ | ||
| 1097 | 1092 | 'Disable Schema Markup Meta Box', |
| 1098 | 1093 | function() use ($option_key) { |
| 1099 | 1094 | $disabled = Metasync::get_option('general')['disable_schema_markup_metabox'] ?? false; |
| 1100 | 1095 | printf( |
| 1101 | - '<input type="checkbox" id="disable_schema_markup_metabox" name="' . $option_key . '[general][disable_schema_markup_metabox]" value="1" %s />', | |
| 1096 | + '<input type="checkbox" id="disable_schema_markup_metabox" name="' . esc_attr($option_key) . '[general][disable_schema_markup_metabox]" value="1" %s />', | |
| 1102 | 1097 | $disabled ? 'checked' : '' |
| 1103 | 1098 | ); |
| 1104 | - printf('<span class="description"> Hide the Schema Markup meta box and stop %1$s emitting any JSON-LD, including site-wide Local SEO markup. While disabled, %1$s does not manage or override this data — another SEO plugin, or none, is free to handle it. Saved values are kept.</span>', Metasync::get_effective_plugin_name('MetaSync')); | |
| 1099 | + printf('<span class="description"> Hide the Schema Markup meta box and stop %1$s emitting any JSON-LD, including site-wide Local SEO markup. While disabled, %1$s does not manage or override this data — another SEO plugin, or none, is free to handle it. Saved values are kept.</span>', esc_html(Metasync::get_effective_plugin_name('MetaSync'))); | |
| 1105 | 1100 | }, |
| 1106 | 1101 | $page_slug . '_general', |
| 1107 | 1102 | $SECTION_METASYNC |
| 1108 | 1103 | ); |
| @@ -1112,12 +1107,12 @@ | ||
| 1112 | 1107 | 'Disable Language Alternates Meta Box', |
| 1113 | 1108 | function() use ($option_key) { |
| 1114 | 1109 | $disabled = Metasync::get_option('general')['disable_language_alternates_metabox'] ?? false; |
| 1115 | 1110 | printf( |
| 1116 | - '<input type="checkbox" id="disable_language_alternates_metabox" name="' . $option_key . '[general][disable_language_alternates_metabox]" value="1" %s />', | |
| 1111 | + '<input type="checkbox" id="disable_language_alternates_metabox" name="' . esc_attr($option_key) . '[general][disable_language_alternates_metabox]" value="1" %s />', | |
| 1117 | 1112 | $disabled ? 'checked' : '' |
| 1118 | 1113 | ); |
| 1119 | - printf('<span class="description"> Hide the Language Alternates (hreflang) panel in the block editor and stop %1$s emitting any %2$slink rel="alternate" hreflang%3$s tags on the front end, including the auto-detected WPML entries. While disabled, %1$s does not manage or override this data — another SEO plugin, or WPML itself, is free to handle it. Saved values are kept and restored if you re-enable this.</span>', Metasync::get_effective_plugin_name('MetaSync'), '<', '>'); | |
| 1114 | + printf('<span class="description"> Hide the Language Alternates (hreflang) panel in the block editor and stop %1$s emitting any %2$slink rel="alternate" hreflang%3$s tags on the front end, including the auto-detected WPML entries. While disabled, %1$s does not manage or override this data — another SEO plugin, or WPML itself, is free to handle it. Saved values are kept and restored if you re-enable this.</span>', esc_html(Metasync::get_effective_plugin_name('MetaSync')), '<', '>'); | |
| 1120 | 1115 | }, |
| 1121 | 1116 | $page_slug . '_general', |
| 1122 | 1117 | $SECTION_METASYNC |
| 1123 | 1118 | ); |
| @@ -1127,12 +1122,12 @@ | ||
| 1127 | 1122 | 'Disable SEO Meta Box', |
| 1128 | 1123 | function() use ($option_key) { |
| 1129 | 1124 | $disabled = Metasync::get_option('general')['disable_seo_metabox'] ?? false; |
| 1130 | 1125 | printf( |
| 1131 | - '<input type="checkbox" id="disable_seo_metabox" name="' . $option_key . '[general][disable_seo_metabox]" value="1" %s />', | |
| 1126 | + '<input type="checkbox" id="disable_seo_metabox" name="' . esc_attr($option_key) . '[general][disable_seo_metabox]" value="1" %s />', | |
| 1132 | 1127 | $disabled ? 'checked' : '' |
| 1133 | 1128 | ); |
| 1134 | - printf('<span class="description"> Hide the SEO Title & Meta Description meta box on post/page edit screens</span>'); | |
| 1129 | + echo '<span class="description"> Hide the SEO Title & Meta Description meta box on post/page edit screens</span>'; | |
| 1135 | 1130 | }, |
| 1136 | 1131 | $page_slug . '_general', |
| 1137 | 1132 | $SECTION_METASYNC |
| 1138 | 1133 | ); |
| @@ -1142,9 +1137,9 @@ | ||
| 1142 | 1137 | 'Open External Links in New Tab/Window', |
| 1143 | 1138 | function() use ($option_key) { |
| 1144 | 1139 | $enabled = Metasync::get_option('general')['open_external_links'] ?? false; |
| 1145 | 1140 | printf( |
| 1146 | - '<input type="checkbox" id="open_external_links" name="' . $option_key . '[general][open_external_links]" value="1" %s />', | |
| 1141 | + '<input type="checkbox" id="open_external_links" name="' . esc_attr($option_key) . '[general][open_external_links]" value="1" %s />', | |
| 1147 | 1142 | $enabled ? 'checked' : '' |
| 1148 | 1143 | ); |
| 1149 | 1144 | printf('<span class="description"> Automatically add <code>target="_blank"</code> attribute to external links appearing in your posts, pages, and other post types when rendered by %s. The attribute is applied when the url is displayed.</span>', esc_html(Metasync::get_whitelabel_otto_name())); |
| 1150 | 1145 | }, |
| @@ -1160,11 +1155,11 @@ | ||
| 1160 | 1155 | $current_permalink_structure = get_option('permalink_structure'); |
| 1161 | 1156 | $current_rewrite_rules = get_option('rewrite_rules'); |
| 1162 | 1157 | // Check if the current permalink structure is set to "Plain" |
| 1163 | 1158 | if (($current_permalink_structure == '/%post_id%/' || $current_permalink_structure == '') && $current_rewrite_rules == '') { |
| 1164 | - printf('<span class="description" style="color:#ff0000;opacity:1;">To ensure compatibility, Please Update your Permalink structure to any option other than "plain. For any Inquiries contact support <a href="' . get_admin_url() . 'options-permalink.php">Check Setting</a> </span>'); | |
| 1159 | + echo '<span class="description" style="color:#ff0000;opacity:1;">To ensure compatibility, Please Update your Permalink structure to any option other than "plain. For any Inquiries contact support <a href="' . esc_url(get_admin_url() . 'options-permalink.php') . '">Check Setting</a> </span>'; | |
| 1165 | 1160 | } else { |
| 1166 | - printf('<span class="description" style="color:#008000;opacity:1;">Permalink is Okay </span>'); | |
| 1161 | + echo '<span class="description" style="color:#008000;opacity:1;">Permalink is Okay </span>'; | |
| 1167 | 1162 | } |
| 1168 | 1163 | }, |
| 1169 | 1164 | $page_slug . '_general', |
| 1170 | 1165 | $SECTION_METASYNC |
| @@ -1176,9 +1171,9 @@ | ||
| 1176 | 1171 | 'Hide Dashboard', |
| 1177 | 1172 | function() use ($option_key) { |
| 1178 | 1173 | $hide_dashboard = Metasync::get_option('general')['hide_dashboard_framework'] ?? ''; |
| 1179 | 1174 | printf( |
| 1180 | - '<input type="checkbox" id="hide_dashboard_framework" name="' . $option_key . '[general][hide_dashboard_framework]" value="true" %s />', | |
| 1175 | + '<input type="checkbox" id="hide_dashboard_framework" name="' . esc_attr($option_key) . '[general][hide_dashboard_framework]" value="true" %s />', | |
| 1181 | 1176 | isset($hide_dashboard) && $hide_dashboard == 'true' ? 'checked' : '' |
| 1182 | 1177 | ); |
| 1183 | 1178 | printf('<span class="description"> Hide the %s dashboard</span>', esc_html(Metasync_Settings_Registration::instance()->get_effective_menu_title())); |
| 1184 | 1179 | }, |
| @@ -1194,9 +1189,9 @@ | ||
| 1194 | 1189 | 'Show ' . $this->get_effective_menu_title() . ' Status in Admin Bar', |
| 1195 | 1190 | function() use ($option_key) { |
| 1196 | 1191 | $show_admin_bar = Metasync::get_option('general')['show_admin_bar_status'] ?? true; |
| 1197 | 1192 | printf( |
| 1198 | - '<input type="checkbox" id="show_admin_bar_status" name="' . $option_key . '[general][show_admin_bar_status]" value="true" %s />', | |
| 1193 | + '<input type="checkbox" id="show_admin_bar_status" name="' . esc_attr($option_key) . '[general][show_admin_bar_status]" value="true" %s />', | |
| 1199 | 1194 | $show_admin_bar ? 'checked' : '' |
| 1200 | 1195 | ); |
| 1201 | 1196 | printf('<span class="description">Show the %s status indicator in the WordPress admin bar.</span>', esc_html(Metasync::get_effective_plugin_name())); |
| 1202 | 1197 | }, |
| @@ -1203,24 +1198,8 @@ | ||
| 1203 | 1198 | $page_slug . '_general', |
| 1204 | 1199 | $SECTION_METASYNC |
| 1205 | 1200 | ); |
| 1206 | 1201 | |
| 1207 | - # Adding the "Enable Auto-updates" setting | |
| 1208 | - add_settings_field( | |
| 1209 | - 'enable_auto_updates', | |
| 1210 | - 'Enable Automatic Updates', | |
| 1211 | - function() use ($option_key) { | |
| 1212 | - $enable_auto_updates = Metasync::get_option('general')['enable_auto_updates'] ?? false; | |
| 1213 | - printf( | |
| 1214 | - '<input type="checkbox" id="enable_auto_updates" name="' . $option_key . '[general][enable_auto_updates]" value="true" %s />', | |
| 1215 | - $enable_auto_updates ? 'checked' : '' | |
| 1216 | - ); | |
| 1217 | - printf('<span class="description">Allow WordPress to automatically update this plugin when new versions are available.</span>'); | |
| 1218 | - }, | |
| 1219 | - $page_slug . '_general', | |
| 1220 | - $SECTION_METASYNC | |
| 1221 | - ); | |
| 1222 | - | |
| 1223 | 1202 | # Add User Role Sync Setting |
| 1224 | 1203 | add_settings_field( |
| 1225 | 1204 | 'content_genius_sync_roles', |
| 1226 | 1205 | 'Content Genius User Roles to Sync', |
| @@ -1322,9 +1301,9 @@ | ||
| 1322 | 1301 | echo '<select id="default_page_builder" name="' . esc_attr($option_key) . '[general][default_page_builder]" style="min-width: 300px;">'; |
| 1323 | 1302 | |
| 1324 | 1303 | foreach ($builders as $key => $builder) { |
| 1325 | 1304 | $is_detected = $builder['detected']; |
| 1326 | - $label = esc_html($builder['label']); | |
| 1305 | + $label = $builder['label']; | |
| 1327 | 1306 | if ($is_detected && $key !== 'gutenberg') { |
| 1328 | 1307 | $label .= ' — Detected'; |
| 1329 | 1308 | } elseif (!$is_detected) { |
| 1330 | 1309 | $label .= ' — Not Detected'; |
| @@ -1336,9 +1315,9 @@ | ||
| 1336 | 1315 | '<option value="%s" %s%s>%s</option>', |
| 1337 | 1316 | esc_attr($key), |
| 1338 | 1317 | selected(empty($current) ? 'gutenberg' : $current, $key, false), |
| 1339 | 1318 | $is_detected ? '' : ' disabled', |
| 1340 | - $label | |
| 1319 | + esc_html($label) | |
| 1341 | 1320 | ); |
| 1342 | 1321 | } |
| 1343 | 1322 | |
| 1344 | 1323 | echo '</select>'; |
| @@ -1387,9 +1366,9 @@ | ||
| 1387 | 1366 | printf( |
| 1388 | 1367 | '<a href="%s" class="button button-secondary"><span class="dashicons dashicons-download" style="margin-top:3px;font-size:15px;width:15px;height:15px;"></span> Import from SEO Plugins</a>', |
| 1389 | 1368 | esc_url(admin_url('admin.php?page=' . Metasync_Admin::$page_slug . '-import-external')) |
| 1390 | 1369 | ); |
| 1391 | - printf('<p class="description">Import settings and data from other SEO plugins (Yoast, Rank Math, AIOSEO, etc).</p>'); | |
| 1370 | + echo '<p class="description">Import settings and data from other SEO plugins (Yoast, Rank Math, AIOSEO, etc).</p>'; | |
| 1392 | 1371 | }, |
| 1393 | 1372 | $page_slug . '_general', |
| 1394 | 1373 | $SECTION_METASYNC |
| 1395 | 1374 | ); |
| @@ -1404,10 +1383,10 @@ | ||
| 1404 | 1383 | 'white_label_plugin_name', |
| 1405 | 1384 | 'Plugin Name' . Metasync::get_tooltip_icon_html('wl_plugin_name_tooltip', 'The name shown for this plugin throughout the WordPress admin — menus, page titles, and system messages. Replace it with your own brand name (max 18 characters).'), |
| 1406 | 1385 | function() use ($option_key) { |
| 1407 | 1386 | $value = Metasync::get_option('general')['white_label_plugin_name'] ?? ''; |
| 1408 | - printf('<input type="text" name="' . $option_key . '[general][white_label_plugin_name]" value="' . esc_attr($value) . '" maxlength="18" />'); | |
| 1409 | - printf('<p class="description">This name will be used for general plugin branding (WordPress menus, page titles, and system messages). Maximum 18 characters.</p>'); | |
| 1387 | + echo '<input type="text" name="' . esc_attr($option_key) . '[general][white_label_plugin_name]" value="' . esc_attr($value) . '" maxlength="18" />'; | |
| 1388 | + echo '<p class="description">This name will be used for general plugin branding (WordPress menus, page titles, and system messages). Maximum 18 characters.</p>'; | |
| 1410 | 1389 | }, |
| 1411 | 1390 | $page_slug . '_branding', |
| 1412 | 1391 | $SECTION_METASYNC |
| 1413 | 1392 | ); |
| @@ -1416,9 +1395,9 @@ | ||
| 1416 | 1395 | 'whitelabel_otto_name', |
| 1417 | 1396 | 'OTTO Name' . Metasync::get_tooltip_icon_html('wl_otto_name_tooltip', 'The name used wherever OTTO is mentioned in the plugin (e.g. "Enable [Name] Server Side Rendering"). Rename it to match your own product branding.'), |
| 1418 | 1397 | function() use ($option_key) { |
| 1419 | 1398 | $value = Metasync::get_option('general')['whitelabel_otto_name'] ?? ''; |
| 1420 | - printf('<input type="text" name="' . $option_key . '[general][whitelabel_otto_name]" value="' . esc_attr($value) . '" />'); | |
| 1399 | + echo '<input type="text" name="' . esc_attr($option_key) . '[general][whitelabel_otto_name]" value="' . esc_attr($value) . '" />'; | |
| 1421 | 1400 | $example_name = !empty($value) ? $value : 'OTTO'; |
| 1422 | 1401 | printf('<p class="description">This name will be used for OTTO feature references (e.g., "Enable %s Server Side Rendering").</p>', esc_html($example_name)); |
| 1423 | 1402 | }, |
| 1424 | 1403 | $page_slug . '_branding', |
| @@ -1430,9 +1409,9 @@ | ||
| 1430 | 1409 | 'Logo (Light Theme)' . Metasync::get_tooltip_icon_html('wl_logo_light_tooltip', 'Your logo shown in the admin dashboard when it\'s set to light mode. Leave blank to use the default logo.'), |
| 1431 | 1410 | function() use ($option_key) { |
| 1432 | 1411 | $whitelabel_settings = Metasync::get_whitelabel_settings(); |
| 1433 | 1412 | $value = $whitelabel_settings['logo_light'] ?? ''; |
| 1434 | - printf('<input type="url" name="' . $option_key . '[whitelabel][logo_light]" value="' . esc_attr($value) . '" size="60" />'); | |
| 1413 | + echo '<input type="url" name="' . esc_attr($option_key) . '[whitelabel][logo_light]" value="' . esc_attr($value) . '" size="60" />'; | |
| 1435 | 1414 | printf('<p class="description">Displayed when the admin UI is in light mode. Leave blank to use the default %s logo.</p>', esc_html(Metasync::get_effective_plugin_name())); |
| 1436 | 1415 | }, |
| 1437 | 1416 | $page_slug . '_branding', |
| 1438 | 1417 | $SECTION_METASYNC |
| @@ -1443,9 +1422,9 @@ | ||
| 1443 | 1422 | 'Logo (Dark Theme)' . Metasync::get_tooltip_icon_html('wl_logo_dark_tooltip', 'Your logo shown in the admin dashboard when it\'s set to dark mode. Leave blank to use the default logo.'), |
| 1444 | 1423 | function() use ($option_key) { |
| 1445 | 1424 | $whitelabel_settings = Metasync::get_whitelabel_settings(); |
| 1446 | 1425 | $value = $whitelabel_settings['logo_dark'] ?? ''; |
| 1447 | - printf('<input type="url" name="' . $option_key . '[whitelabel][logo_dark]" value="' . esc_attr($value) . '" size="60" />'); | |
| 1426 | + echo '<input type="url" name="' . esc_attr($option_key) . '[whitelabel][logo_dark]" value="' . esc_attr($value) . '" size="60" />'; | |
| 1448 | 1427 | printf('<p class="description">Displayed when the admin UI is in dark mode. Leave blank to use the default %s logo.</p>', esc_html(Metasync::get_effective_plugin_name())); |
| 1449 | 1428 | }, |
| 1450 | 1429 | $page_slug . '_branding', |
| 1451 | 1430 | $SECTION_METASYNC |
| @@ -1456,10 +1435,10 @@ | ||
| 1456 | 1435 | 'Dashboard URL' . Metasync::get_tooltip_icon_html('wl_dashboard_url_tooltip', 'The web address of your own branded dashboard, shown to clients instead of the Search Atlas dashboard link. This is cosmetic only — it doesn\'t change where your data is actually stored.'), |
| 1457 | 1436 | function() use ($option_key) { |
| 1458 | 1437 | $whitelabel_settings = Metasync::get_whitelabel_settings(); |
| 1459 | 1438 | $value = $whitelabel_settings['domain'] ?? ''; |
| 1460 | - printf('<input type="url" name="' . $option_key . '[whitelabel][domain]" value="' . esc_attr($value) . '" size="60" />'); | |
| 1461 | - printf('<p class="description">Enter your whitelabel dashboard URL (e.g., https://yourdashboard.com). Used for branding purposes.</p>'); | |
| 1439 | + echo '<input type="url" name="' . esc_attr($option_key) . '[whitelabel][domain]" value="' . esc_attr($value) . '" size="60" />'; | |
| 1440 | + echo '<p class="description">Enter your whitelabel dashboard URL (e.g., https://yourdashboard.com). Used for branding purposes.</p>'; | |
| 1462 | 1441 | }, |
| 1463 | 1442 | $page_slug . '_branding', |
| 1464 | 1443 | $SECTION_METASYNC |
| 1465 | 1444 | ); |
| @@ -1467,9 +1446,9 @@ | ||
| 1467 | 1446 | 'white_label_plugin_description', |
| 1468 | 1447 | 'Plugin Description', |
| 1469 | 1448 | function() use ($option_key) { |
| 1470 | 1449 | $value = Metasync::get_option('general')['white_label_plugin_description'] ?? ''; |
| 1471 | - printf('<input type="text" name="' . $option_key . '[general][white_label_plugin_description]" value="' . esc_attr($value) . '" />'); | |
| 1450 | + echo '<input type="text" name="' . esc_attr($option_key) . '[general][white_label_plugin_description]" value="' . esc_attr($value) . '" />'; | |
| 1472 | 1451 | }, |
| 1473 | 1452 | $page_slug . '_branding', |
| 1474 | 1453 | $SECTION_METASYNC |
| 1475 | 1454 | ); |
| @@ -1478,9 +1457,9 @@ | ||
| 1478 | 1457 | 'white_label_plugin_author', |
| 1479 | 1458 | 'Author', |
| 1480 | 1459 | function() use ($option_key) { |
| 1481 | 1460 | $value = Metasync::get_option('general')['white_label_plugin_author'] ?? ''; |
| 1482 | - printf('<input type="text" name="' . $option_key . '[general][white_label_plugin_author]" value="' . esc_attr($value) . '" />'); | |
| 1461 | + echo '<input type="text" name="' . esc_attr($option_key) . '[general][white_label_plugin_author]" value="' . esc_attr($value) . '" />'; | |
| 1483 | 1462 | }, |
| 1484 | 1463 | $page_slug . '_branding', |
| 1485 | 1464 | $SECTION_METASYNC |
| 1486 | 1465 | ); |
| @@ -1489,9 +1468,9 @@ | ||
| 1489 | 1468 | 'white_label_plugin_author_uri', |
| 1490 | 1469 | 'Author URI', |
| 1491 | 1470 | function() use ($option_key) { |
| 1492 | 1471 | $value = Metasync::get_option('general')['white_label_plugin_author_uri'] ?? ''; |
| 1493 | - # printf('<input type="text" name="' . $option_key . '[general][white_label_plugin_author_uri]" value="' . esc_attr($value) . '" />'); | |
| 1472 | + # printf('<input type="text" name="' . esc_attr($option_key) . '[general][white_label_plugin_author_uri]" value="' . esc_attr($value) . '" />'); | |
| 1494 | 1473 | # Fixed printf usage |
| 1495 | 1474 | printf('<input type="text" name="%s" value="%s" />', esc_attr($option_key . '[general][white_label_plugin_author_uri]'), esc_attr($value) ); |
| 1496 | 1475 | |
| 1497 | 1476 | }, |
| @@ -1502,9 +1481,9 @@ | ||
| 1502 | 1481 | 'white_label_plugin_uri', |
| 1503 | 1482 | 'Plugin URI', |
| 1504 | 1483 | function() use ($option_key) { |
| 1505 | 1484 | $value = Metasync::get_option('general')['white_label_plugin_uri'] ?? ''; // New option for Plugin URI |
| 1506 | - printf('<input type="text" name="' . $option_key . '[general][white_label_plugin_uri]" value="' . esc_attr($value) . '" />'); | |
| 1485 | + echo '<input type="text" name="' . esc_attr($option_key) . '[general][white_label_plugin_uri]" value="' . esc_attr($value) . '" />'; | |
| 1507 | 1486 | }, |
| 1508 | 1487 | $page_slug . '_branding', |
| 1509 | 1488 | $SECTION_METASYNC |
| 1510 | 1489 | ); |
| @@ -1518,10 +1497,10 @@ | ||
| 1518 | 1497 | 'white_label_plugin_menu_slug', |
| 1519 | 1498 | 'Menu Slug', |
| 1520 | 1499 | function() use ($option_key) { |
| 1521 | 1500 | $value = Metasync::get_option('general')['white_label_plugin_menu_slug'] ?? ''; |
| 1522 | - printf('<input type="text" name="' . $option_key . '[general][white_label_plugin_menu_slug]" value="' . esc_attr($value) . '" placeholder="hip-advanced-seo" />'); | |
| 1523 | - printf('<p class="description">Short identifier for the plugin\'s admin URL — lowercase letters, numbers, and dashes only (e.g. <code>hip-advanced-seo</code>). Don\'t paste a full web address.</p>'); | |
| 1501 | + echo '<input type="text" name="' . esc_attr($option_key) . '[general][white_label_plugin_menu_slug]" value="' . esc_attr($value) . '" placeholder="hip-advanced-seo" />'; | |
| 1502 | + echo '<p class="description">Short identifier for the plugin\'s admin URL — lowercase letters, numbers, and dashes only (e.g. <code>hip-advanced-seo</code>). Don\'t paste a full web address.</p>'; | |
| 1524 | 1503 | }, |
| 1525 | 1504 | $page_slug . '_branding', |
| 1526 | 1505 | $SECTION_METASYNC |
| 1527 | 1506 | ); |
| @@ -1529,9 +1508,9 @@ | ||
| 1529 | 1508 | 'white_label_plugin_menu_icon', |
| 1530 | 1509 | 'Menu Icon', |
| 1531 | 1510 | function() use ($option_key) { |
| 1532 | 1511 | $value = Metasync::get_option('general')['white_label_plugin_menu_icon'] ?? ''; |
| 1533 | - echo '<input type="text" name="' . $option_key . '[general][white_label_plugin_menu_icon]" value="' . esc_attr($value) . '" />'; | |
| 1512 | + echo '<input type="text" name="' . esc_attr($option_key) . '[general][white_label_plugin_menu_icon]" value="' . esc_attr($value) . '" />'; | |
| 1534 | 1513 | }, |
| 1535 | 1514 | $page_slug . '_branding', |
| 1536 | 1515 | $SECTION_METASYNC |
| 1537 | 1516 | ); |
| @@ -1546,22 +1525,22 @@ | ||
| 1546 | 1525 | |
| 1547 | 1526 | // Output radio button for Default Style.css active |
| 1548 | 1527 | |
| 1549 | 1528 | printf( |
| 1550 | - '<input type="radio" id="enable_default" name="' . $option_key . '[general][enabled_plugin_css]" value="default" %s />', | |
| 1529 | + '<input type="radio" id="enable_default" name="' . esc_attr($option_key) . '[general][enabled_plugin_css]" value="default" %s />', | |
| 1551 | 1530 | ($enabled_plugin_css == 'default'||$enabled_plugin_css =='') ? 'checked' : '' |
| 1552 | 1531 | ); |
| 1553 | - printf('<label for="enable_default">Default</label><br>'); | |
| 1532 | + echo '<label for="enable_default">Default</label><br>'; | |
| 1554 | 1533 | |
| 1555 | 1534 | |
| 1556 | 1535 | // Output radio button for Metasync Style |
| 1557 | 1536 | printf( |
| 1558 | - '<input type="radio" id="enable_metasync" name="' . $option_key . '[general][enabled_plugin_css]" value="metasync" %s />', | |
| 1537 | + '<input type="radio" id="enable_metasync" name="' . esc_attr($option_key) . '[general][enabled_plugin_css]" value="metasync" %s />', | |
| 1559 | 1538 | ($enabled_plugin_css == 'metasync') ? 'checked' : '' |
| 1560 | 1539 | ); |
| 1561 | - printf('<label for="enable_metasync">Metasync Style</label>'); | |
| 1540 | + echo '<label for="enable_metasync">Metasync Style</label>'; | |
| 1562 | 1541 | |
| 1563 | - printf('<p class="description"> Choose the default page Style Sheet: Default or MetaSync.</p>'); | |
| 1542 | + echo '<p class="description"> Choose the default page Style Sheet: Default or MetaSync.</p>'; | |
| 1564 | 1543 | }, |
| 1565 | 1544 | $page_slug . '_branding', |
| 1566 | 1545 | $SECTION_METASYNC |
| 1567 | 1546 | ); |
| @@ -1571,12 +1550,12 @@ | ||
| 1571 | 1550 | 'enabled_elementor_plugin_css', |
| 1572 | 1551 | 'Choose Elementor Font Style', |
| 1573 | 1552 | function() use ($option_key) { |
| 1574 | 1553 | $enabled_elementor_plugin_css = Metasync::get_option('general')['enabled_elementor_plugin_css'] ?? 'default'; |
| 1575 | - printf('<select name="' . $option_key . '[general][enabled_elementor_plugin_css]" id="heading_style">'); | |
| 1576 | - printf('<option value="default"'.selected($enabled_elementor_plugin_css, 'default', false).'>Default</option>'); | |
| 1577 | - printf('<option value="custom" '. selected($enabled_elementor_plugin_css, 'custom', false) . '>Custom</option>'); | |
| 1578 | - printf('</select>'); | |
| 1554 | + echo '<select name="' . esc_attr($option_key) . '[general][enabled_elementor_plugin_css]" id="heading_style">'; | |
| 1555 | + echo '<option value="default"'.selected($enabled_elementor_plugin_css, 'default', false).'>Default</option>'; | |
| 1556 | + echo '<option value="custom" '. selected($enabled_elementor_plugin_css, 'custom', false) . '>Custom</option>'; | |
| 1557 | + echo '</select>'; | |
| 1579 | 1558 | }, |
| 1580 | 1559 | $page_slug . '_branding', |
| 1581 | 1560 | $SECTION_METASYNC |
| 1582 | 1561 | ); |
| @@ -1584,9 +1563,9 @@ | ||
| 1584 | 1563 | 'enabled_elementor_plugin_css_color', |
| 1585 | 1564 | 'Choose Elementor Font Color', |
| 1586 | 1565 | function() use ($option_key) { |
| 1587 | 1566 | $enabled_elementor_plugin_css_color = Metasync::get_option('general')['enabled_elementor_plugin_css_color'] ?? '#000000'; |
| 1588 | - printf('<input type="color" id="elementor_default_color_metasync" name="' . $option_key . '[general][enabled_elementor_plugin_css_color]" value="'.$enabled_elementor_plugin_css_color.'">'); | |
| 1567 | + echo '<input type="color" id="elementor_default_color_metasync" name="' . esc_attr($option_key) . '[general][enabled_elementor_plugin_css_color]" value="'.esc_attr($enabled_elementor_plugin_css_color).'">'; | |
| 1589 | 1568 | }, |
| 1590 | 1569 | $page_slug . '_branding', |
| 1591 | 1570 | $SECTION_METASYNC |
| 1592 | 1571 | ); |
| @@ -1597,10 +1576,10 @@ | ||
| 1597 | 1576 | function() use ($option_key) { |
| 1598 | 1577 | // Decrypted for display — this field only renders after the |
| 1599 | 1578 | // whitelabel password gate has been passed. |
| 1600 | 1579 | $value = Metasync::get_whitelabel_password(); |
| 1601 | - printf('<input type="password" name="' . $option_key . '[whitelabel][settings_password]" value="' . esc_attr($value) . '" size="30" autocomplete="new-password" />'); | |
| 1602 | - printf('<p class="description">Set a custom password to protect the branding settings section.</p>'); | |
| 1580 | + echo '<input type="password" name="' . esc_attr($option_key) . '[whitelabel][settings_password]" value="' . esc_attr($value) . '" size="30" autocomplete="new-password" />'; | |
| 1581 | + echo '<p class="description">Set a custom password to protect the branding settings section.</p>'; | |
| 1603 | 1582 | }, |
| 1604 | 1583 | $page_slug . '_branding', |
| 1605 | 1584 | $SECTION_METASYNC |
| 1606 | 1585 | ); |
| @@ -1611,10 +1590,10 @@ | ||
| 1611 | 1590 | function() use ($option_key) { |
| 1612 | 1591 | $whitelabel_settings = Metasync::get_whitelabel_settings(); |
| 1613 | 1592 | $value = $whitelabel_settings['recovery_email'] ?? ''; |
| 1614 | 1593 | $has_password = !empty($whitelabel_settings['settings_password']); |
| 1615 | - printf('<input type="email" name="' . $option_key . '[whitelabel][recovery_email]" value="' . esc_attr($value) . '" size="30" autocomplete="email" %s />', $has_password ? 'required' : ''); | |
| 1616 | - printf('<p class="description">Email address to receive password recovery. <strong>Required when password is set.</strong></p>'); | |
| 1594 | + printf('<input type="email" name="' . esc_attr($option_key) . '[whitelabel][recovery_email]" value="' . esc_attr($value) . '" size="30" autocomplete="email" %s />', $has_password ? 'required' : ''); | |
| 1595 | + echo '<p class="description">Email address to receive password recovery. <strong>Required when password is set.</strong></p>'; | |
| 1617 | 1596 | }, |
| 1618 | 1597 | $page_slug . '_branding', |
| 1619 | 1598 | $SECTION_METASYNC |
| 1620 | 1599 | ); |
| @@ -1644,11 +1623,11 @@ | ||
| 1644 | 1623 | <td><input type="text" name="%s[whitelabel][quick_links][%d][label]" value="%s" placeholder="Link label" style="width:100%%" /></td> |
| 1645 | 1624 | <td><input type="url" name="%s[whitelabel][quick_links][%d][url]" value="%s" placeholder="https://…" style="width:100%%" /></td> |
| 1646 | 1625 | <td style="text-align:center"><input type="checkbox" name="%s[whitelabel][quick_links][%d][external]" value="1" %s /></td> |
| 1647 | 1626 | </tr>', |
| 1648 | - esc_attr($option_key), $i, $label, | |
| 1649 | - esc_attr($option_key), $i, $url, | |
| 1650 | - esc_attr($option_key), $i, checked($external, true, false) | |
| 1627 | + esc_attr($option_key), esc_attr($i), esc_attr($label), | |
| 1628 | + esc_attr($option_key), esc_attr($i), esc_attr($url), | |
| 1629 | + esc_attr($option_key), esc_attr($i), checked($external, true, false) | |
| 1651 | 1630 | ); |
| 1652 | 1631 | } |
| 1653 | 1632 | echo '</tbody></table>'; |
| 1654 | 1633 | }, |
| @@ -1675,9 +1654,9 @@ | ||
| 1675 | 1654 | 'Organization Name', |
| 1676 | 1655 | function() use ($option_key) { |
| 1677 | 1656 | $schema = Metasync::get_option('schema') ?? []; |
| 1678 | 1657 | $value = $schema['org_name'] ?? ''; |
| 1679 | - printf('<input type="text" name="' . $option_key . '[schema][org_name]" value="%s" size="40" placeholder="Your organization name" />', esc_attr($value)); | |
| 1658 | + printf('<input type="text" name="' . esc_attr($option_key) . '[schema][org_name]" value="%s" size="40" placeholder="Your organization name" />', esc_attr($value)); | |
| 1680 | 1659 | }, |
| 1681 | 1660 | $schema_page, |
| 1682 | 1661 | 'metasync_schema_org' |
| 1683 | 1662 | ); |
| @@ -1687,9 +1666,9 @@ | ||
| 1687 | 1666 | 'Organization URL', |
| 1688 | 1667 | function() use ($option_key) { |
| 1689 | 1668 | $schema = Metasync::get_option('schema') ?? []; |
| 1690 | 1669 | $value = $schema['org_url'] ?? ''; |
| 1691 | - printf('<input type="url" name="' . $option_key . '[schema][org_url]" value="%s" size="40" placeholder="https://example.com" />', esc_attr($value)); | |
| 1670 | + printf('<input type="url" name="' . esc_attr($option_key) . '[schema][org_url]" value="%s" size="40" placeholder="https://example.com" />', esc_attr($value)); | |
| 1692 | 1671 | }, |
| 1693 | 1672 | $schema_page, |
| 1694 | 1673 | 'metasync_schema_org' |
| 1695 | 1674 | ); |
| @@ -1699,9 +1678,9 @@ | ||
| 1699 | 1678 | 'Organization Logo URL' . Metasync::get_tooltip_icon_html('schema_org_logo_tooltip', 'A direct link to your logo image. Google uses this in your Organization knowledge panel — use a clear, square-ish image on a plain background, ideally at least 112x112 pixels.'), |
| 1700 | 1679 | function() use ($option_key) { |
| 1701 | 1680 | $schema = Metasync::get_option('schema') ?? []; |
| 1702 | 1681 | $value = $schema['org_logo'] ?? ''; |
| 1703 | - printf('<input type="url" name="' . $option_key . '[schema][org_logo]" value="%s" size="40" placeholder="https://example.com/logo.png" />', esc_attr($value)); | |
| 1682 | + printf('<input type="url" name="' . esc_attr($option_key) . '[schema][org_logo]" value="%s" size="40" placeholder="https://example.com/logo.png" />', esc_attr($value)); | |
| 1704 | 1683 | }, |
| 1705 | 1684 | $schema_page, |
| 1706 | 1685 | 'metasync_schema_org' |
| 1707 | 1686 | ); |
| @@ -1711,9 +1690,9 @@ | ||
| 1711 | 1690 | 'Contact Telephone', |
| 1712 | 1691 | function() use ($option_key) { |
| 1713 | 1692 | $schema = Metasync::get_option('schema') ?? []; |
| 1714 | 1693 | $value = $schema['org_contact_telephone'] ?? ''; |
| 1715 | - printf('<input type="text" name="' . $option_key . '[schema][org_contact_telephone]" value="%s" size="30" placeholder="+1-555-1234" />', esc_attr($value)); | |
| 1694 | + printf('<input type="text" name="' . esc_attr($option_key) . '[schema][org_contact_telephone]" value="%s" size="30" placeholder="+1-555-1234" />', esc_attr($value)); | |
| 1716 | 1695 | }, |
| 1717 | 1696 | $schema_page, |
| 1718 | 1697 | 'metasync_schema_org' |
| 1719 | 1698 | ); |
| @@ -1723,9 +1702,9 @@ | ||
| 1723 | 1702 | 'Contact Type' . Metasync::get_tooltip_icon_html('schema_org_contact_type_tooltip', 'What this phone number is for, using schema.org wording such as "customer support", "sales", or "technical support". It tells search engines how the number should be labeled.'), |
| 1724 | 1703 | function() use ($option_key) { |
| 1725 | 1704 | $schema = Metasync::get_option('schema') ?? []; |
| 1726 | 1705 | $value = $schema['org_contact_type'] ?? ''; |
| 1727 | - printf('<input type="text" name="' . $option_key . '[schema][org_contact_type]" value="%s" size="30" placeholder="customer support" />', esc_attr($value)); | |
| 1706 | + printf('<input type="text" name="' . esc_attr($option_key) . '[schema][org_contact_type]" value="%s" size="30" placeholder="customer support" />', esc_attr($value)); | |
| 1728 | 1707 | }, |
| 1729 | 1708 | $schema_page, |
| 1730 | 1709 | 'metasync_schema_org' |
| 1731 | 1710 | ); |
| @@ -1735,9 +1714,9 @@ | ||
| 1735 | 1714 | 'Social Profile URLs' . Metasync::get_tooltip_icon_html('schema_org_same_as_tooltip', 'Links to your official profiles on other sites (Facebook, X/Twitter, LinkedIn, Wikipedia, etc.), one per line. This is the schema.org "sameAs" property — it helps search engines confirm these accounts are really you.'), |
| 1736 | 1715 | function() use ($option_key) { |
| 1737 | 1716 | $schema = Metasync::get_option('schema') ?? []; |
| 1738 | 1717 | $value = $schema['org_same_as'] ?? ''; |
| 1739 | - printf('<textarea name="' . $option_key . '[schema][org_same_as]" rows="4" cols="50" placeholder="One URL per line https://facebook.com/... https://twitter.com/...">%s</textarea>', esc_textarea($value)); | |
| 1718 | + printf('<textarea name="' . esc_attr($option_key) . '[schema][org_same_as]" rows="4" cols="50" placeholder="One URL per line https://facebook.com/... https://twitter.com/...">%s</textarea>', esc_textarea($value)); | |
| 1740 | 1719 | echo '<p class="description">Enter one social profile URL per line.</p>'; |
| 1741 | 1720 | }, |
| 1742 | 1721 | $schema_page, |
| 1743 | 1722 | 'metasync_schema_org' |
| @@ -1757,9 +1736,9 @@ | ||
| 1757 | 1736 | 'WebSite Name', |
| 1758 | 1737 | function() use ($option_key) { |
| 1759 | 1738 | $schema = Metasync::get_option('schema') ?? []; |
| 1760 | 1739 | $value = $schema['website_name'] ?? ''; |
| 1761 | - printf('<input type="text" name="' . $option_key . '[schema][website_name]" value="%s" size="40" placeholder="Your website name" />', esc_attr($value)); | |
| 1740 | + printf('<input type="text" name="' . esc_attr($option_key) . '[schema][website_name]" value="%s" size="40" placeholder="Your website name" />', esc_attr($value)); | |
| 1762 | 1741 | }, |
| 1763 | 1742 | $schema_page, |
| 1764 | 1743 | 'metasync_schema_website' |
| 1765 | 1744 | ); |
| @@ -1769,9 +1748,9 @@ | ||
| 1769 | 1748 | 'WebSite URL', |
| 1770 | 1749 | function() use ($option_key) { |
| 1771 | 1750 | $schema = Metasync::get_option('schema') ?? []; |
| 1772 | 1751 | $value = $schema['website_url'] ?? ''; |
| 1773 | - printf('<input type="url" name="' . $option_key . '[schema][website_url]" value="%s" size="40" placeholder="https://example.com" />', esc_attr($value)); | |
| 1752 | + printf('<input type="url" name="' . esc_attr($option_key) . '[schema][website_url]" value="%s" size="40" placeholder="https://example.com" />', esc_attr($value)); | |
| 1774 | 1753 | }, |
| 1775 | 1754 | $schema_page, |
| 1776 | 1755 | 'metasync_schema_website' |
| 1777 | 1756 | ); |
| @@ -1782,9 +1761,9 @@ | ||
| 1782 | 1761 | function() use ($option_key) { |
| 1783 | 1762 | $schema = Metasync::get_option('schema') ?? []; |
| 1784 | 1763 | $value = $schema['website_searchbox'] ?? false; |
| 1785 | 1764 | printf( |
| 1786 | - '<input type="checkbox" name="' . $option_key . '[schema][website_searchbox]" value="1" %s />', | |
| 1765 | + '<input type="checkbox" name="' . esc_attr($option_key) . '[schema][website_searchbox]" value="1" %s />', | |
| 1787 | 1766 | checked($value, true, false) |
| 1788 | 1767 | ); |
| 1789 | 1768 | echo '<span class="description">Adds SearchAction to WebSite schema for Google Sitelinks Searchbox.</span>'; |
| 1790 | 1769 | }, |
| @@ -1807,9 +1786,9 @@ | ||
| 1807 | 1786 | function() use ($option_key) { |
| 1808 | 1787 | $schema = Metasync::get_option('schema') ?? []; |
| 1809 | 1788 | $value = $schema['override_woocommerce_schema'] ?? false; |
| 1810 | 1789 | printf( |
| 1811 | - '<input type="checkbox" name="' . $option_key . '[schema][override_woocommerce_schema]" value="1" %s />', | |
| 1790 | + '<input type="checkbox" name="' . esc_attr($option_key) . '[schema][override_woocommerce_schema]" value="1" %s />', | |
| 1812 | 1791 | checked($value, true, false) |
| 1813 | 1792 | ); |
| 1814 | 1793 | echo '<span class="description">When unchecked (default), MetaSync suppresses its Product schema when WooCommerce is active to avoid duplication. Check to override WooCommerce\'s native Product schema.</span>'; |
| 1815 | 1794 | }, |
| @@ -1863,9 +1842,9 @@ | ||
| 1863 | 1842 | 'baidu_site_verification', |
| 1864 | 1843 | 'Baidu' . Metasync::get_tooltip_icon_html('baidu_site_verification_tooltip', 'Paste the verification code Baidu Webmaster gave you. This lets Baidu confirm you own this site — it does not change anything visitors see.'), |
| 1865 | 1844 | function() use ($option_key) { |
| 1866 | 1845 | $value = Metasync::get_option('searchengines')['baidu_site_verification'] ?? ''; |
| 1867 | - printf( '<input type="text" id="baidu_site_verification" name="' . $option_key . '[searchengines][baidu_site_verification]" value="%s" size="50" />', esc_attr( $value ) ); | |
| 1846 | + printf( '<input type="text" id="baidu_site_verification" name="' . esc_attr($option_key) . '[searchengines][baidu_site_verification]" value="%s" size="50" />', esc_attr( $value ) ); | |
| 1868 | 1847 | }, |
| 1869 | 1848 | $page_slug . '_searchengines-verification', |
| 1870 | 1849 | $SECTION_SEARCHENGINE |
| 1871 | 1850 | ); |
| @@ -1874,9 +1853,9 @@ | ||
| 1874 | 1853 | 'alexa_site_verification', |
| 1875 | 1854 | 'Alexa' . Metasync::get_tooltip_icon_html('alexa_site_verification_tooltip', 'Paste the verification code your Alexa/site directory gave you. This confirms you own this site — it does not change anything visitors see.'), |
| 1876 | 1855 | function() use ($option_key) { |
| 1877 | 1856 | $value = Metasync::get_option('searchengines')['alexa_site_verification'] ?? ''; |
| 1878 | - printf( '<input type="text" id="alexa_site_verification" name="' . $option_key . '[searchengines][alexa_site_verification]" value="%s" size="50" />', esc_attr( $value ) ); | |
| 1857 | + printf( '<input type="text" id="alexa_site_verification" name="' . esc_attr($option_key) . '[searchengines][alexa_site_verification]" value="%s" size="50" />', esc_attr( $value ) ); | |
| 1879 | 1858 | }, |
| 1880 | 1859 | $page_slug . '_searchengines-verification', |
| 1881 | 1860 | $SECTION_SEARCHENGINE |
| 1882 | 1861 | ); |
| @@ -1885,9 +1864,9 @@ | ||
| 1885 | 1864 | 'norton_save_site_verification', |
| 1886 | 1865 | 'Norton Safe Web' . Metasync::get_tooltip_icon_html('norton_site_verification_tooltip', 'Paste the verification code Norton Safe Web gave you. This confirms you own this site — it does not change anything visitors see.'), |
| 1887 | 1866 | function() use ($option_key) { |
| 1888 | 1867 | $value = Metasync::get_option('searchengines')['norton_save_site_verification'] ?? ''; |
| 1889 | - printf( '<input type="text" id="norton_save_site_verification" name="' . $option_key . '[searchengines][norton_save_site_verification]" value="%s" size="50" />', esc_attr( $value ) ); | |
| 1868 | + printf( '<input type="text" id="norton_save_site_verification" name="' . esc_attr($option_key) . '[searchengines][norton_save_site_verification]" value="%s" size="50" />', esc_attr( $value ) ); | |
| 1890 | 1869 | }, |
| 1891 | 1870 | $page_slug . '_searchengines-verification', |
| 1892 | 1871 | $SECTION_SEARCHENGINE |
| 1893 | 1872 | ); |
| @@ -2103,10 +2082,10 @@ | ||
| 2103 | 2082 | * @return array Sanitized settings |
| 2104 | 2083 | */ |
| 2105 | 2084 | public function sanitize($input) |
| 2106 | 2085 | { |
| 2107 | - $submitted_generation = isset($_POST['metasync_pw_reset_generation']) | |
| 2108 | - ? absint($_POST['metasync_pw_reset_generation']) | |
| 2086 | + $submitted_generation = isset($_POST['metasync_pw_reset_generation']) // phpcs:ignore WordPress.Security.NonceVerification.Missing -- sanitize callback, the caller already verified the nonce | |
| 2087 | + ? absint($_POST['metasync_pw_reset_generation']) // phpcs:ignore WordPress.Security.NonceVerification.Missing -- sanitize callback, the caller already verified the nonce | |
| 2109 | 2088 | : null; |
| 2110 | 2089 | // Legacy/stale forms that include a password but no reset generation |
| 2111 | 2090 | // must never be allowed to overwrite a newer recovery password. |
| 2112 | 2091 | if (!self::$allow_recovery_password_write |
| @@ -2150,15 +2129,15 @@ | ||
| 2150 | 2129 | |
| 2151 | 2130 | # Determine which tab is being submitted (same logic as AJAX handler) |
| 2152 | 2131 | # Check POST first (from AJAX), then GET (from form action URL) |
| 2153 | 2132 | $active_tab = 'general'; |
| 2154 | - if (isset($_POST['active_tab'])) { | |
| 2155 | - $active_tab = sanitize_text_field($_POST['active_tab']); | |
| 2156 | - } elseif (isset($_GET['tab'])) { | |
| 2157 | - $active_tab = sanitize_text_field($_GET['tab']); | |
| 2158 | - } elseif (isset($_POST['_wp_http_referer'])) { | |
| 2133 | + if (isset($_POST['active_tab'])) { // phpcs:ignore WordPress.Security.NonceVerification.Missing -- sanitize callback, the caller already verified the nonce | |
| 2134 | + $active_tab = sanitize_text_field(wp_unslash($_POST['active_tab'])); // phpcs:ignore WordPress.Security.NonceVerification.Missing -- sanitize callback, the caller already verified the nonce | |
| 2135 | + } elseif (isset($_GET['tab'])) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- sanitize callback, the caller already verified the nonce | |
| 2136 | + $active_tab = sanitize_text_field(wp_unslash($_GET['tab'])); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- sanitize callback, the caller already verified the nonce | |
| 2137 | + } elseif (isset($_POST['_wp_http_referer'])) { // phpcs:ignore WordPress.Security.NonceVerification.Missing -- sanitize callback, the caller already verified the nonce | |
| 2159 | 2138 | # Parse referer URL to get tab parameter |
| 2160 | - $referer = wp_parse_url($_POST['_wp_http_referer']); | |
| 2139 | + $referer = wp_parse_url(esc_url_raw(wp_unslash($_POST['_wp_http_referer']))); // phpcs:ignore WordPress.Security.NonceVerification.Missing -- sanitize callback, the caller already verified the nonce | |
| 2161 | 2140 | if (isset($referer['query'])) { |
| 2162 | 2141 | parse_str($referer['query'], $referer_params); |
| 2163 | 2142 | if (isset($referer_params['tab'])) { |
| 2164 | 2143 | $active_tab = sanitize_text_field($referer_params['tab']); |
| @@ -2748,9 +2727,10 @@ | ||
| 2748 | 2727 | * Moved from Metasync_Admin – the admin class now delegates here. |
| 2749 | 2728 | */ |
| 2750 | 2729 | public function meta_sync_save_settings() |
| 2751 | 2730 | { |
| 2752 | - if (!isset($_POST['meta_sync_nonce']) || !wp_verify_nonce($_POST['meta_sync_nonce'], 'meta_sync_general_setting_nonce')) { | |
| 2731 | + $meta_sync_nonce = isset($_POST['meta_sync_nonce']) ? sanitize_text_field(wp_unslash($_POST['meta_sync_nonce'])) : ''; | |
| 2732 | + if (!wp_verify_nonce($meta_sync_nonce, 'meta_sync_general_setting_nonce')) { | |
| 2753 | 2733 | wp_send_json_error(array('message' => 'Invalid nonce')); |
| 2754 | 2734 | return; |
| 2755 | 2735 | } |
| 2756 | 2736 | |
| @@ -2797,9 +2777,9 @@ | ||
| 2797 | 2777 | $url_fields = [ |
| 2798 | 2778 | 'white_label_plugin_author_uri', 'white_label_plugin_uri' |
| 2799 | 2779 | ]; |
| 2800 | 2780 | |
| 2801 | - $bool_fields = ['otto_disable_on_loggedin', 'otto_disable_preview_button', 'otto_disable_for_bots' , 'hide_dashboard_framework', 'show_admin_bar_status', 'enable_auto_updates', 'disable_common_robots_metabox', 'disable_advance_robots_metabox', 'disable_redirection_metabox', 'disable_canonical_metabox', 'disable_social_opengraph_metabox', 'disable_schema_markup_metabox', 'disable_language_alternates_metabox', 'disable_seo_metabox', 'open_external_links', Metasync_Seo_Backup::CONSENT_OPTION_KEY]; | |
| 2781 | + $bool_fields = ['otto_disable_on_loggedin', 'otto_disable_preview_button', 'otto_disable_for_bots' , 'hide_dashboard_framework', 'show_admin_bar_status','disable_common_robots_metabox', 'disable_advance_robots_metabox', 'disable_redirection_metabox', 'disable_canonical_metabox', 'disable_social_opengraph_metabox', 'disable_schema_markup_metabox', 'disable_language_alternates_metabox', 'disable_seo_metabox', 'open_external_links', Metasync_Seo_Backup::CONSENT_OPTION_KEY]; | |
| 2802 | 2782 | |
| 2803 | 2783 | $url_fields = ['white_label_plugin_author_uri', 'white_label_plugin_uri']; |
| 2804 | 2784 | |
| 2805 | 2785 | $metasync_options = Metasync::get_option(); |
| @@ -2811,9 +2791,9 @@ | ||
| 2811 | 2791 | } |
| 2812 | 2792 | |
| 2813 | 2793 | $validation_errors = []; |
| 2814 | 2794 | |
| 2815 | - $active_tab = isset($_POST['active_tab']) ? sanitize_text_field($_POST['active_tab']) : 'general'; | |
| 2795 | + $active_tab = isset($_POST['active_tab']) ? sanitize_text_field(wp_unslash($_POST['active_tab'])) : 'general'; | |
| 2816 | 2796 | $general_tab_submitted = ($active_tab === 'general'); |
| 2817 | 2797 | $whitelabel_tab_submitted = ($active_tab === 'whitelabel'); |
| 2818 | 2798 | |
| 2819 | 2799 | // Whitelabel field validation issues are collected per-field and reported back |
| @@ -2823,9 +2803,10 @@ | ||
| 2823 | 2803 | foreach ($text_fields as $field) { |
| 2824 | 2804 | |
| 2825 | 2805 | if (isset($_POST['metasync_options']['general'][$field])) { |
| 2826 | 2806 | |
| 2827 | - $value = trim($_POST['metasync_options']['general'][$field]); | |
| 2807 | + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- every storing branch below sanitises via sanitize_text_field/sanitize_title/esc_url_raw before the value reaches the option. | |
| 2808 | + $value = trim(wp_unslash($_POST['metasync_options']['general'][$field])); | |
| 2828 | 2809 | |
| 2829 | 2810 | // searchatlas_api_key must be clearable to support key removal |
| 2830 | 2811 | $clearable_fields = [ |
| 2831 | 2812 | 'searchatlas_api_key', |
| @@ -2862,9 +2843,9 @@ | ||
| 2862 | 2843 | } elseif (filter_var($value, FILTER_VALIDATE_URL)) { |
| 2863 | 2844 | |
| 2864 | 2845 | $image_extensions = ['png', 'svg']; |
| 2865 | 2846 | |
| 2866 | - $path = parse_url($value, PHP_URL_PATH); | |
| 2847 | + $path = wp_parse_url($value, PHP_URL_PATH); | |
| 2867 | 2848 | $extension = strtolower(pathinfo($path, PATHINFO_EXTENSION)); |
| 2868 | 2849 | |
| 2869 | 2850 | if (in_array($extension, $image_extensions, true)) { |
| 2870 | 2851 | $metasync_options['general'][$field] = esc_url_raw($value); |
| @@ -2878,9 +2859,9 @@ | ||
| 2878 | 2859 | // Self-correcting slug: a URL-shaped value is reduced to a valid WP |
| 2879 | 2860 | // menu slug so it can never break sidebar link generation. |
| 2880 | 2861 | $metasync_options['general'][$field] = sanitize_title($value); |
| 2881 | 2862 | } else { |
| 2882 | - $metasync_options['general'][$field] = sanitize_text_field($_POST['metasync_options']['general'][$field]); | |
| 2863 | + $metasync_options['general'][$field] = sanitize_text_field(wp_unslash($_POST['metasync_options']['general'][$field])); | |
| 2883 | 2864 | } |
| 2884 | 2865 | } |
| 2885 | 2866 | } |
| 2886 | 2867 | |
| @@ -2887,9 +2868,9 @@ | ||
| 2887 | 2868 | $textarea_fields = ['otto_bot_whitelist', 'otto_bot_blacklist']; |
| 2888 | 2869 | if ($general_tab_submitted) { |
| 2889 | 2870 | foreach ($textarea_fields as $field) { |
| 2890 | 2871 | if (isset($_POST['metasync_options']['general'][$field])) { |
| 2891 | - $metasync_options['general'][$field] = sanitize_textarea_field($_POST['metasync_options']['general'][$field]); | |
| 2872 | + $metasync_options['general'][$field] = sanitize_textarea_field(wp_unslash($_POST['metasync_options']['general'][$field])); | |
| 2892 | 2873 | } else { |
| 2893 | 2874 | $metasync_options['general'][$field] = ''; |
| 2894 | 2875 | } |
| 2895 | 2876 | } |
| @@ -2897,9 +2878,9 @@ | ||
| 2897 | 2878 | |
| 2898 | 2879 | if ($general_tab_submitted) { |
| 2899 | 2880 | foreach ($bool_fields as $field) { |
| 2900 | 2881 | if (isset($_POST['metasync_options']['general'][$field])) { |
| 2901 | - $metasync_options['general'][$field] = filter_var($_POST['metasync_options']['general'][$field], FILTER_VALIDATE_BOOLEAN); | |
| 2882 | + $metasync_options['general'][$field] = filter_var(wp_unslash($_POST['metasync_options']['general'][$field]), FILTER_VALIDATE_BOOLEAN); | |
| 2902 | 2883 | }else { |
| 2903 | 2884 | $metasync_options['general'][$field] = false; |
| 2904 | 2885 | } |
| 2905 | 2886 | } |
| @@ -2918,9 +2899,10 @@ | ||
| 2918 | 2899 | if ($general_tab_submitted || $whitelabel_tab_submitted) { |
| 2919 | 2900 | foreach ($url_fields as $field) { |
| 2920 | 2901 | if (isset($_POST['metasync_options']['general'][$field])) { |
| 2921 | 2902 | |
| 2922 | - $value = trim($_POST['metasync_options']['general'][$field]); | |
| 2903 | + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- every storing branch below sanitises via sanitize_text_field/sanitize_title/esc_url_raw before the value reaches the option. | |
| 2904 | + $value = trim(wp_unslash($_POST['metasync_options']['general'][$field])); | |
| 2923 | 2905 | |
| 2924 | 2906 | $whitelabel_clearable_url_fields = [ |
| 2925 | 2907 | 'white_label_plugin_author_uri', |
| 2926 | 2908 | 'white_label_plugin_uri' |
| @@ -2936,9 +2918,9 @@ | ||
| 2936 | 2918 | } |
| 2937 | 2919 | |
| 2938 | 2920 | if (filter_var($value, FILTER_VALIDATE_URL)) { |
| 2939 | 2921 | |
| 2940 | - $parsed_url = parse_url($value); | |
| 2922 | + $parsed_url = wp_parse_url($value); | |
| 2941 | 2923 | $host = isset($parsed_url['host']) ? $parsed_url['host'] : ''; |
| 2942 | 2924 | |
| 2943 | 2925 | if (strpos($host, '.') !== false || filter_var($host, FILTER_VALIDATE_IP)) { |
| 2944 | 2926 | $metasync_options['general'][$field] = esc_url_raw($value); |
| @@ -2955,9 +2937,9 @@ | ||
| 2955 | 2937 | } |
| 2956 | 2938 | |
| 2957 | 2939 | if ($general_tab_submitted) { |
| 2958 | 2940 | if (isset($_POST['metasync_options']['general']['content_genius_sync_roles']) && is_array($_POST['metasync_options']['general']['content_genius_sync_roles'])) { |
| 2959 | - $metasync_options['general']['content_genius_sync_roles'] = array_map('sanitize_text_field', $_POST['metasync_options']['general']['content_genius_sync_roles']); | |
| 2941 | + $metasync_options['general']['content_genius_sync_roles'] = array_map('sanitize_text_field', wp_unslash($_POST['metasync_options']['general']['content_genius_sync_roles'])); | |
| 2960 | 2942 | } else { |
| 2961 | 2943 | $metasync_options['general']['content_genius_sync_roles'] = array(); |
| 2962 | 2944 | } |
| 2963 | 2945 | } |
| @@ -2969,9 +2951,10 @@ | ||
| 2969 | 2951 | if ($general_tab_submitted |
| 2970 | 2952 | && isset($_POST['metasync_options']['breadcrumbs']) |
| 2971 | 2953 | && is_array($_POST['metasync_options']['breadcrumbs']) |
| 2972 | 2954 | ) { |
| 2973 | - $breadcrumbs_input = $_POST['metasync_options']['breadcrumbs']; | |
| 2955 | + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- each key is sanitised below (bool cast for flags, sanitize_text_field for the separator). | |
| 2956 | + $breadcrumbs_input = wp_unslash($_POST['metasync_options']['breadcrumbs']); | |
| 2974 | 2957 | |
| 2975 | 2958 | if (!isset($metasync_options['breadcrumbs']) || !is_array($metasync_options['breadcrumbs'])) { |
| 2976 | 2959 | $metasync_options['breadcrumbs'] = array(); |
| 2977 | 2960 | } |
| @@ -3022,9 +3005,9 @@ | ||
| 3022 | 3005 | $metasync_options['common_meta_settings'] = []; |
| 3023 | 3006 | } |
| 3024 | 3007 | foreach ($og_toggle_fields as $field) { |
| 3025 | 3008 | $posted = isset($_POST['metasync_options']['common_meta_settings'][$field]) |
| 3026 | - ? sanitize_text_field($_POST['metasync_options']['common_meta_settings'][$field]) | |
| 3009 | + ? sanitize_text_field(wp_unslash($_POST['metasync_options']['common_meta_settings'][$field])) | |
| 3027 | 3010 | : ''; |
| 3028 | 3011 | $metasync_options['common_meta_settings'][$field] = ($posted === 'true') ? 'true' : 'false'; |
| 3029 | 3012 | } |
| 3030 | 3013 | } |
| @@ -3031,14 +3014,15 @@ | ||
| 3031 | 3014 | |
| 3032 | 3015 | if ($general_tab_submitted && isset($_POST['metasync_options']['general']['default_page_builder'])) { |
| 3033 | 3016 | require_once plugin_dir_path(dirname(__FILE__)) . 'custom-pages/class-metasync-html-to-builder-converter.php'; |
| 3034 | 3017 | $available_builders = Metasync_HTML_To_Builder_Converter::get_available_builders(); |
| 3035 | - $builder_value = sanitize_text_field($_POST['metasync_options']['general']['default_page_builder']); | |
| 3018 | + $builder_value = sanitize_text_field(wp_unslash($_POST['metasync_options']['general']['default_page_builder'])); | |
| 3036 | 3019 | if (isset($available_builders[$builder_value]) && $available_builders[$builder_value]['detected']) { |
| 3037 | 3020 | $metasync_options['general']['default_page_builder'] = $builder_value; |
| 3038 | 3021 | } else { |
| 3039 | 3022 | $metasync_options['general']['default_page_builder'] = 'gutenberg'; |
| 3040 | 3023 | if (isset($available_builders[$builder_value]) && !$available_builders[$builder_value]['detected']) { |
| 3024 | + /* translators: %s: page builder name. */ | |
| 3041 | 3025 | $validation_errors[] = sprintf(__('Builder "%s" is not detected on this site. Reverted to Gutenberg.', 'metasync'), $available_builders[$builder_value]['label']); |
| 3042 | 3026 | } |
| 3043 | 3027 | } |
| 3044 | 3028 | } |
| @@ -3043,10 +3027,13 @@ | ||
| 3043 | 3027 | } |
| 3044 | 3028 | } |
| 3045 | 3029 | |
| 3046 | 3030 | if ($whitelabel_tab_submitted && isset($_POST['metasync_options']['whitelabel'])) { |
| 3047 | - $gp = isset($_POST['metasync_options']['general']) && is_array($_POST['metasync_options']['general']) ? $_POST['metasync_options']['general'] : []; | |
| 3048 | - $wp = isset($_POST['metasync_options']['whitelabel']) && is_array($_POST['metasync_options']['whitelabel']) ? $_POST['metasync_options']['whitelabel'] : []; | |
| 3031 | + // Values are only previewed from the just-sanitised $metasync_options below; nothing here is stored. | |
| 3032 | + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- preview-only read | |
| 3033 | + $gp = isset($_POST['metasync_options']['general']) && is_array($_POST['metasync_options']['general']) ? wp_unslash($_POST['metasync_options']['general']) : []; | |
| 3034 | + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- preview-only read | |
| 3035 | + $wp = isset($_POST['metasync_options']['whitelabel']) && is_array($_POST['metasync_options']['whitelabel']) ? wp_unslash($_POST['metasync_options']['whitelabel']) : []; | |
| 3049 | 3036 | $plugin_name = isset($gp['white_label_plugin_name']) ? trim((string) $gp['white_label_plugin_name']) : ''; |
| 3050 | 3037 | $logo_light = isset($wp['logo_light']) ? trim((string) $wp['logo_light']) : ''; |
| 3051 | 3038 | $logo_dark = isset($wp['logo_dark']) ? trim((string) $wp['logo_dark']) : ''; |
| 3052 | 3039 | $author = isset($gp['white_label_plugin_author']) ? trim((string) $gp['white_label_plugin_author']) : ''; |
| @@ -3210,9 +3197,10 @@ | ||
| 3210 | 3197 | } |
| 3211 | 3198 | |
| 3212 | 3199 | if (isset($_POST['metasync_options']['whitelabel'])) { |
| 3213 | 3200 | |
| 3214 | - $whitelabel_data = $_POST['metasync_options']['whitelabel']; | |
| 3201 | + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- every stored key below is validated/sanitised (FILTER_VALIDATE_URL + esc_url_raw for logos, sanitize_* for text). | |
| 3202 | + $whitelabel_data = wp_unslash($_POST['metasync_options']['whitelabel']); | |
| 3215 | 3203 | $existing_whitelabel = $metasync_options['whitelabel'] ?? []; |
| 3216 | 3204 | |
| 3217 | 3205 | if (isset($whitelabel_data['logo'])) { |
| 3218 | 3206 | $logo_value = trim($whitelabel_data['logo']); |
| @@ -3253,9 +3241,9 @@ | ||
| 3253 | 3241 | } |
| 3254 | 3242 | } |
| 3255 | 3243 | |
| 3256 | 3244 | if (isset($whitelabel_data['settings_password'])) { |
| 3257 | - $password_value = (string) wp_unslash($whitelabel_data['settings_password']); | |
| 3245 | + $password_value = (string) $whitelabel_data['settings_password']; | |
| 3258 | 3246 | |
| 3259 | 3247 | $hide_settings_enabled = isset($whitelabel_data['hide_settings']) && $whitelabel_data['hide_settings'] == '1'; |
| 3260 | 3248 | |
| 3261 | 3249 | if ($hide_settings_enabled && empty($password_value)) { |
| @@ -3353,9 +3341,9 @@ | ||
| 3353 | 3341 | |
| 3354 | 3342 | } |
| 3355 | 3343 | |
| 3356 | 3344 | $redirect_url = isset($_GET['tab']) ? |
| 3357 | - admin_url('admin.php?page=' . Metasync_Admin::$page_slug . '-settings&tab='.$_GET['tab']) : | |
| 3345 | + admin_url('admin.php?page=' . Metasync_Admin::$page_slug . '-settings&tab=' . sanitize_text_field(wp_unslash($_GET['tab']))) : | |
| 3358 | 3346 | admin_url('admin.php?page=' . Metasync_Admin::$page_slug . '-settings'); |
| 3359 | 3347 | |
| 3360 | 3348 | // Also save edge cache settings if present in the payload (section renders inside this form) |
| 3361 | 3349 | if (class_exists('Metasync_Edge_Cache_Settings')) { |
| @@ -3362,8 +3350,9 @@ | ||
| 3362 | 3350 | Metasync_Edge_Cache_Settings::save_from_post(); |
| 3363 | 3351 | } |
| 3364 | 3352 | |
| 3365 | 3353 | if ($general_tab_submitted && isset($_POST['metasync_llms_txt_settings'])) { |
| 3354 | + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- sanitised by sanitize_llms_txt_settings() before storage. | |
| 3366 | 3355 | $llms_input = wp_unslash($_POST['metasync_llms_txt_settings']); |
| 3367 | 3356 | if (is_array($llms_input)) { |
| 3368 | 3357 | update_option('metasync_llms_txt_settings', $this->sanitize_llms_txt_settings($llms_input)); |
| 3369 | 3358 | } |
| @@ -3415,9 +3404,10 @@ | ||
| 3415 | 3404 | * Moved from Metasync_Admin – the admin class now delegates here. |
| 3416 | 3405 | */ |
| 3417 | 3406 | public function ajax_save_execution_settings() |
| 3418 | 3407 | { |
| 3419 | - if (!isset($_POST['execution_settings_nonce']) || !wp_verify_nonce($_POST['execution_settings_nonce'], 'metasync_execution_settings_nonce')) { | |
| 3408 | + $execution_nonce = isset($_POST['execution_settings_nonce']) ? sanitize_text_field(wp_unslash($_POST['execution_settings_nonce'])) : ''; | |
| 3409 | + if (!wp_verify_nonce($execution_nonce, 'metasync_execution_settings_nonce')) { | |
| 3420 | 3410 | wp_send_json_error(array('message' => 'Invalid security token. Please refresh the page and try again.')); |
| 3421 | 3411 | return; |
| 3422 | 3412 | } |
| 3423 | 3413 | |
| @@ -4008,16 +3998,19 @@ | ||
| 4008 | 3998 | public function ajax_save_headless_settings() |
| 4009 | 3999 | { |
| 4010 | 4000 | $prefix = self::HEADLESS_FIELD_PREFIX; |
| 4011 | 4001 | |
| 4012 | - if (!isset($_POST[self::HEADLESS_NONCE_FIELD]) || !wp_verify_nonce($_POST[self::HEADLESS_NONCE_FIELD], self::HEADLESS_NONCE_ACTION)) { | |
| 4002 | + $headless_nonce = isset($_POST[self::HEADLESS_NONCE_FIELD]) ? sanitize_text_field(wp_unslash($_POST[self::HEADLESS_NONCE_FIELD])) : ''; | |
| 4003 | + if (!wp_verify_nonce($headless_nonce, self::HEADLESS_NONCE_ACTION)) { | |
| 4013 | 4004 | wp_send_json_error(array('message' => 'Invalid security token. Please refresh the page and try again.')); |
| 4014 | 4005 | } elseif (!Metasync::current_user_has_plugin_access()) { |
| 4015 | 4006 | wp_send_json_error(array('message' => 'Insufficient permissions to save settings.')); |
| 4016 | 4007 | } else { |
| 4008 | + // phpcs:disable WordPress.Security.ValidatedSanitizedInput -- sanitised via Metasync_Headless_Config::normalize_domain() inside save_headless_settings(). | |
| 4017 | 4009 | $submitted_domain = isset($_POST[$prefix . 'frontend_domain']) |
| 4018 | 4010 | ? trim((string) wp_unslash($_POST[$prefix . 'frontend_domain'])) |
| 4019 | 4011 | : ''; |
| 4012 | + // phpcs:enable WordPress.Security.ValidatedSanitizedInput | |
| 4020 | 4013 | |
| 4021 | 4014 | $stored = $this->save_headless_settings($_POST); |
| 4022 | 4015 | |
| 4023 | 4016 | if (!$this->headless_settings_persisted($stored)) { |
| @@ -4059,13 +4052,26 @@ | ||
| 4059 | 4052 | */ |
| 4060 | 4053 | public function meta_sync_save_seo_controls() |
| 4061 | 4054 | { |
| 4062 | 4055 | try { |
| 4063 | - if (!isset($_POST['meta_sync_seo_controls_nonce']) || !wp_verify_nonce($_POST['meta_sync_seo_controls_nonce'], 'meta_sync_seo_controls_nonce')) { | |
| 4056 | + $seo_controls_nonce = isset($_POST['meta_sync_seo_controls_nonce']) ? sanitize_text_field(wp_unslash($_POST['meta_sync_seo_controls_nonce'])) : ''; | |
| 4057 | + if (!wp_verify_nonce($seo_controls_nonce, 'meta_sync_seo_controls_nonce')) { | |
| 4064 | 4058 | wp_send_json_error(array('message' => 'Invalid nonce')); |
| 4065 | 4059 | return; |
| 4066 | 4060 | } |
| 4067 | 4061 | |
| 4062 | + // Same nonce-then-capability shape as the other settings save | |
| 4063 | + // handlers: the nonce is not authorization, so a logged-in user | |
| 4064 | + // without plugin access must still be refused here. | |
| 4065 | + if (!Metasync::current_user_has_plugin_access()) { | |
| 4066 | + wp_send_json_error(array('message' => 'Insufficient permissions.'), 403); | |
| 4067 | + // The return is unreachable in WordPress (wp_send_json_error | |
| 4068 | + // terminates the request) but keeps the handler safe under the | |
| 4069 | + // non-terminating stubs the unit tests run with. | |
| 4070 | + // @phpstan-ignore-next-line deadCode.unreachable | |
| 4071 | + return; | |
| 4072 | + } | |
| 4073 | + | |
| 4068 | 4074 | $current_options = Metasync::get_option(); |
| 4069 | 4075 | |
| 4070 | 4076 | $original_options = json_decode(json_encode($current_options), true); |
| 4071 | 4077 | |
| @@ -4131,10 +4137,9 @@ | ||
| 4131 | 4137 | } |
| 4132 | 4138 | wp_send_json_error(array('message' => $error_message)); |
| 4133 | 4139 | } |
| 4134 | 4140 | } catch (Exception $e) { |
| 4135 | - error_log('Indexation Control AJAX Exception: ' . $e->getMessage()); | |
| 4136 | - error_log('Indexation Control AJAX Stack trace: ' . $e->getTraceAsString()); | |
| 4141 | + error_log('Indexation Control AJAX Exception: ' . $e->getMessage()); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- genuine failure path, bounded, no secrets | |
| 4137 | 4142 | wp_send_json_error(array('message' => 'Error saving settings: ' . $e->getMessage())); |
| 4138 | 4143 | } |
| 4139 | 4144 | } |
| 4140 | 4145 | |
| @@ -4146,12 +4151,12 @@ | ||
| 4146 | 4151 | * @return bool True on success, false on failure |
| 4147 | 4152 | */ |
| 4148 | 4153 | public function save_bing_inline_settings_ajax() |
| 4149 | 4154 | { |
| 4150 | - $api_key = isset($_POST['metasync_bing_api_key_inline']) ? sanitize_text_field(wp_unslash($_POST['metasync_bing_api_key_inline'])) : ''; | |
| 4151 | - $endpoint = isset($_POST['metasync_bing_endpoint_inline']) ? sanitize_text_field(wp_unslash($_POST['metasync_bing_endpoint_inline'])) : 'indexnow'; | |
| 4152 | - $post_types = isset($_POST['metasync_bing_post_types_inline']) && is_array($_POST['metasync_bing_post_types_inline']) ? array_map('sanitize_title', wp_unslash($_POST['metasync_bing_post_types_inline'])) : []; | |
| 4153 | - $disable_other_plugins = isset($_POST['metasync_bing_disable_other_plugins_inline']) ? true : false; | |
| 4155 | + $api_key = isset($_POST['metasync_bing_api_key_inline']) ? sanitize_text_field(wp_unslash($_POST['metasync_bing_api_key_inline'])) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing -- caller verifies the SEO controls nonce first | |
| 4156 | + $endpoint = isset($_POST['metasync_bing_endpoint_inline']) ? sanitize_text_field(wp_unslash($_POST['metasync_bing_endpoint_inline'])) : 'indexnow'; // phpcs:ignore WordPress.Security.NonceVerification.Missing -- caller verifies the SEO controls nonce first | |
| 4157 | + $post_types = isset($_POST['metasync_bing_post_types_inline']) && is_array($_POST['metasync_bing_post_types_inline']) ? array_map('sanitize_title', wp_unslash($_POST['metasync_bing_post_types_inline'])) : []; // phpcs:ignore WordPress.Security.NonceVerification.Missing -- caller verifies the SEO controls nonce first | |
| 4158 | + $disable_other_plugins = isset($_POST['metasync_bing_disable_other_plugins_inline']) ? true : false; // phpcs:ignore WordPress.Security.NonceVerification.Missing -- caller verifies the SEO controls nonce first | |
| 4154 | 4159 | |
| 4155 | 4160 | $existing_settings = get_option('metasync_options_bing_instant_indexing', []); |
| 4156 | 4161 | |
| 4157 | 4162 | $new_settings = [ |
| @@ -4175,9 +4180,9 @@ | ||
| 4175 | 4180 | $safe_key = sanitize_file_name( $api_key ); |
| 4176 | 4181 | $file_path = ABSPATH . $safe_key . '.txt'; |
| 4177 | 4182 | $real_path = realpath( ABSPATH ); |
| 4178 | 4183 | if ( false === $real_path || 0 !== strpos( realpath( dirname( $file_path ) ), $real_path ) ) { |
| 4179 | - error_log( 'Bing IndexNow: Refusing to write outside ABSPATH' ); | |
| 4184 | + error_log( 'Bing IndexNow: Refusing to write outside ABSPATH' ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- genuine failure path, bounded, no secrets | |
| 4180 | 4185 | return false; |
| 4181 | 4186 | } |
| 4182 | 4187 | // serve the key virtually via template_redirect instead of |
| 4183 | 4188 | // writing a physical {key}.txt. An on-disk file is served statically |
| @@ -4190,9 +4195,9 @@ | ||
| 4190 | 4195 | } |
| 4191 | 4196 | Metasync_Bing_Instant_Index::register_virtual_key($safe_key); |
| 4192 | 4197 | |
| 4193 | 4198 | if (file_exists($file_path)) { |
| 4194 | - @unlink($file_path); | |
| 4199 | + @wp_delete_file($file_path); | |
| 4195 | 4200 | } |
| 4196 | 4201 | |
| 4197 | 4202 | $current_options = Metasync::get_option(); |
| 4198 | 4203 | if (!isset($current_options['seo_controls']['enable_binginstantindex']) || $current_options['seo_controls']['enable_binginstantindex'] !== 'true') { |