| @@ -217,14 +217,14 @@ | ||
| 217 | 217 | // ------------------------------------------------------------------ |
| 218 | 218 | |
| 219 | 219 | public function create_admin_settings_page() |
| 220 | 220 | { |
| 221 | - if (isset($_REQUEST['metasync_password_reset'])) { | |
| 221 | + if (isset($_REQUEST['metasync_password_reset'])) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- routing check, the reset form verifies its own nonce | |
| 222 | 222 | Metasync_Admin_Ajax::instance()->render_password_reset_page(); |
| 223 | 223 | return; |
| 224 | 224 | } |
| 225 | 225 | |
| 226 | - $active_tab = isset($_GET['tab']) ? sanitize_key( wp_unslash( $_GET['tab'] ) ) : 'general'; | |
| 226 | + $active_tab = isset($_GET['tab']) ? sanitize_key( wp_unslash( $_GET['tab'] ) ) : 'general'; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only tab selection | |
| 227 | 227 | |
| 228 | 228 | $whitelabel_settings = Metasync::get_whitelabel_settings(); |
| 229 | 229 | |
| 230 | 230 | $user_password = $whitelabel_settings['settings_password'] ?? ''; |
| @@ -250,9 +250,9 @@ | ||
| 250 | 250 | |
| 251 | 251 | $auth = new Metasync_Auth_Manager('whitelabel', 1800); |
| 252 | 252 | $password_validated = $auth->has_access(); |
| 253 | 253 | |
| 254 | - if (isset($_POST['whitelabel_password_submit']) && !$password_validated) { | |
| 254 | + if (isset($_POST['whitelabel_password_submit']) && !$password_validated) { // phpcs:ignore WordPress.Security.NonceVerification.Missing -- read-only access check for a display message | |
| 255 | 255 | $password_error = 'Incorrect password. Please try again.'; |
| 256 | 256 | } |
| 257 | 257 | } |
| 258 | 258 | |
| @@ -908,10 +908,10 @@ | ||
| 908 | 908 | </div> |
| 909 | 909 | <?php endif; ?> |
| 910 | 910 | |
| 911 | 911 | <?php |
| 912 | - if (isset($_GET['debug_mode_enabled']) && $_GET['debug_mode_enabled'] == '1'): | |
| 913 | - $indefinite = isset($_GET['indefinite']) && $_GET['indefinite'] == '1'; | |
| 912 | + if (isset($_GET['debug_mode_enabled']) && $_GET['debug_mode_enabled'] == '1'): // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only result flag for a static notice | |
| 913 | + $indefinite = isset($_GET['indefinite']) && $_GET['indefinite'] == '1'; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only result flag for a static notice | |
| 914 | 914 | ?> |
| 915 | 915 | <div class="notice notice-success inline" style="margin-bottom: 20px;"> |
| 916 | 916 | <p> |
| 917 | 917 | <strong>✅ Success!</strong> Debug mode has been enabled<?php echo $indefinite ? ' indefinitely' : ' for 24 hours'; ?>. |
| @@ -918,9 +918,9 @@ | ||
| 918 | 918 | </p> |
| 919 | 919 | </div> |
| 920 | 920 | <?php endif; ?> |
| 921 | 921 | |
| 922 | - <?php if (isset($_GET['debug_mode_disabled']) && $_GET['debug_mode_disabled'] == '1'): ?> | |
| 922 | + <?php if (isset($_GET['debug_mode_disabled']) && $_GET['debug_mode_disabled'] == '1'): // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only result flag for a static notice ?> | |
| 923 | 923 | <div class="notice notice-info inline" style="margin-bottom: 20px;"> |
| 924 | 924 | <p> |
| 925 | 925 | <strong>ℹ️ Debug Mode Disabled:</strong> Debug mode has been successfully disabled. |
| 926 | 926 | </p> |
| @@ -926,9 +926,9 @@ | ||
| 926 | 926 | </p> |
| 927 | 927 | </div> |
| 928 | 928 | <?php endif; ?> |
| 929 | 929 | |
| 930 | - <?php if (isset($_GET['debug_mode_extended']) && $_GET['debug_mode_extended'] == '1'): ?> | |
| 930 | + <?php if (isset($_GET['debug_mode_extended']) && $_GET['debug_mode_extended'] == '1'): // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only result flag for a static notice ?> | |
| 931 | 931 | <div class="notice notice-success inline" style="margin-bottom: 20px;"> |
| 932 | 932 | <p> |
| 933 | 933 | <strong>✅ Extended!</strong> Debug mode has been extended for another 24 hours. |
| 934 | 934 | </p> |
| @@ -934,9 +934,9 @@ | ||
| 934 | 934 | </p> |
| 935 | 935 | </div> |
| 936 | 936 | <?php endif; ?> |
| 937 | 937 | |
| 938 | - <?php if (isset($_GET['debug_error']) && $_GET['debug_error'] == '1'): ?> | |
| 938 | + <?php if (isset($_GET['debug_error']) && $_GET['debug_error'] == '1'): // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only result flag for a static notice ?> | |
| 939 | 939 | <div class="notice notice-error inline" style="margin-bottom: 20px;"> |
| 940 | 940 | <p> |
| 941 | 941 | <strong>❌ Error:</strong> Unable to perform the debug mode operation. Please try again. |
| 942 | 942 | </p> |
| @@ -1309,41 +1309,41 @@ | ||
| 1309 | 1309 | } |
| 1310 | 1310 | </style> |
| 1311 | 1311 | |
| 1312 | 1312 | <?php if ($active_tab === 'advanced'): ?> |
| 1313 | - <?php if (isset($_GET['settings_cleared']) && $_GET['settings_cleared'] == '1'): ?> | |
| 1313 | + <?php if (isset($_GET['settings_cleared']) && $_GET['settings_cleared'] == '1'): // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only result flag for a static notice ?> | |
| 1314 | 1314 | <div class="notice notice-success is-dismissible"> |
| 1315 | 1315 | <p><strong>✅ Success!</strong> All plugin settings have been cleared successfully and a new Plugin Auth Token has been generated. Please reconfigure the plugin as needed.</p> |
| 1316 | 1316 | </div> |
| 1317 | 1317 | <?php endif; ?> |
| 1318 | 1318 | |
| 1319 | - <?php if (isset($_GET['clear_settings_error']) && $_GET['clear_settings_error'] == '1'): ?> | |
| 1319 | + <?php if (isset($_GET['clear_settings_error']) && $_GET['clear_settings_error'] == '1'): // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only result flag for a static notice ?> | |
| 1320 | 1320 | <div class="notice notice-error is-dismissible"> |
| 1321 | 1321 | <p><strong>❌ Error!</strong> Failed to clear settings due to a security check failure. Please try again.</p> |
| 1322 | 1322 | </div> |
| 1323 | 1323 | <?php endif; ?> |
| 1324 | 1324 | |
| 1325 | - <?php if (isset($_GET['log_cleared']) && $_GET['log_cleared'] == '1'): ?> | |
| 1325 | + <?php if (isset($_GET['log_cleared']) && $_GET['log_cleared'] == '1'): // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only result flag for a static notice ?> | |
| 1326 | 1326 | <div class="notice notice-success is-dismissible"> |
| 1327 | 1327 | <p><strong>✅ Success!</strong> Error logs have been cleared successfully.</p> |
| 1328 | 1328 | </div> |
| 1329 | 1329 | <?php endif; ?> |
| 1330 | 1330 | |
| 1331 | - <?php if (isset($_GET['clear_error']) && $_GET['clear_error'] == '1'): ?> | |
| 1331 | + <?php if (isset($_GET['clear_error']) && $_GET['clear_error'] == '1'): // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only result flag for a static notice ?> | |
| 1332 | 1332 | <div class="notice notice-error is-dismissible"> |
| 1333 | 1333 | <p><strong>❌ Error!</strong> Failed to clear error logs due to a security check failure. Please try again.</p> |
| 1334 | 1334 | </div> |
| 1335 | 1335 | <?php endif; ?> |
| 1336 | 1336 | |
| 1337 | - <?php if (isset($_GET['access_roles_saved']) && $_GET['access_roles_saved'] == '1'): ?> | |
| 1337 | + <?php if (isset($_GET['access_roles_saved']) && $_GET['access_roles_saved'] == '1'): // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only result flag for a static notice ?> | |
| 1338 | 1338 | <div class="notice notice-success is-dismissible"> |
| 1339 | 1339 | <p><strong>✅ Success!</strong> Plugin access roles have been saved successfully.</p> |
| 1340 | 1340 | </div> |
| 1341 | 1341 | <?php endif; ?> |
| 1342 | 1342 | |
| 1343 | - <?php if (isset($_GET['access_roles_error']) && $_GET['access_roles_error'] == '1'): ?> | |
| 1343 | + <?php if (isset($_GET['access_roles_error']) && $_GET['access_roles_error'] == '1'): // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only result flag for a static notice ?> | |
| 1344 | 1344 | <div class="notice notice-error is-dismissible"> |
| 1345 | - <p><strong>❌ Error!</strong> Failed to save plugin access roles. <?php echo isset($_GET['message']) ? esc_html(urldecode($_GET['message'])) : 'Please try again.'; ?></p> | |
| 1345 | + <p><strong>❌ Error!</strong> Failed to save plugin access roles. <?php echo isset($_GET['message']) ? esc_html(urldecode($_GET['message'])) : 'Please try again.'; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only error text, escaped on output ?></p> | |
| 1346 | 1346 | </div> |
| 1347 | 1347 | <?php endif; ?> |
| 1348 | 1348 | |
| 1349 | 1349 | <?php endif; ?> |
| @@ -1377,8 +1377,15 @@ | ||
| 1377 | 1377 | } |
| 1378 | 1378 | |
| 1379 | 1379 | public function create_admin_robots_txt_page() |
| 1380 | 1380 | { |
| 1381 | + // The form below rewrites the site's physical robots.txt — restrict | |
| 1382 | + // that to site admins, not just anyone who can open the page via | |
| 1383 | + // plugin_access_roles. The nonce is CSRF protection, not authorization. | |
| 1384 | + if (!empty($_POST) && !current_user_can('manage_options')) { | |
| 1385 | + wp_die(esc_html__('Sorry, you are not allowed to manage robots.txt settings.', 'metasync')); | |
| 1386 | + } | |
| 1387 | + | |
| 1381 | 1388 | ?> |
| 1382 | 1389 | <?php $this->admin->render_layout_open('Robots.txt', 'robots_txt', 'Control which pages search engines can crawl.'); ?> |
| 1383 | 1390 | |
| 1384 | 1391 | <?php |
| @@ -1439,84 +1446,8 @@ | ||
| 1439 | 1446 | |
| 1440 | 1447 | public function create_admin_report_issue_page() |
| 1441 | 1448 | { |
| 1442 | 1449 | require_once plugin_dir_path(dirname(__FILE__)) . 'views/metasync-report-issue.php'; |
| 1443 | - } | |
| 1444 | - | |
| 1445 | - public function create_admin_xml_sitemap_page() | |
| 1446 | - { | |
| 1447 | - require_once plugin_dir_path(dirname(__FILE__)) . 'sitemap/class-metasync-sitemap-generator.php'; | |
| 1448 | - | |
| 1449 | - $sitemap_generator = new Metasync_Sitemap_Generator(); | |
| 1450 | - | |
| 1451 | - if (isset($_POST['metasync_sitemap_nonce'])) { | |
| 1452 | - check_admin_referer('metasync_sitemap_action', 'metasync_sitemap_nonce'); | |
| 1453 | - | |
| 1454 | - if (isset($_POST['generate_sitemap'])) { | |
| 1455 | - $disabled_plugins = $sitemap_generator->disable_other_sitemap_generators(); | |
| 1456 | - | |
| 1457 | - $result = $sitemap_generator->generate_sitemap(); | |
| 1458 | - | |
| 1459 | - if (is_wp_error($result)) { | |
| 1460 | - error_log('[MetaSync] Sitemap generation failed: ' . $result->get_error_message()); | |
| 1461 | - echo '<div class="notice notice-error"><p>' . esc_html__('Sitemap generation failed. Please try again or check the error logs.', 'metasync') . '</p></div>'; | |
| 1462 | - } elseif (false === $result) { | |
| 1463 | - echo '<div class="notice notice-error"><p>' . esc_html__('Sitemap generation failed: the sitemap data could not be stored, so no sitemap is being served. Check your object cache and database write settings, then try again.', 'metasync') . '</p></div>'; | |
| 1464 | - } else { | |
| 1465 | - $message = esc_html__('Sitemap generated successfully!', 'metasync'); | |
| 1466 | - if ($disabled_plugins) { | |
| 1467 | - $message .= ' ' . esc_html__('Conflicting sitemap generators have been automatically disabled.', 'metasync'); | |
| 1468 | - } | |
| 1469 | - | |
| 1470 | - $robots_result = get_transient('metasync_sitemap_robots_updated'); | |
| 1471 | - if ($robots_result && $robots_result['success']) { | |
| 1472 | - if ($robots_result['action'] === 'added') { | |
| 1473 | - $message .= ' ' . esc_html__('Sitemap URL has been added to robots.txt.', 'metasync'); | |
| 1474 | - } elseif ($robots_result['action'] === 'updated') { | |
| 1475 | - $message .= ' ' . esc_html__('Sitemap URL has been updated in robots.txt.', 'metasync'); | |
| 1476 | - } elseif ($robots_result['action'] === 'created') { | |
| 1477 | - $message .= ' ' . esc_html__('robots.txt file has been created with sitemap URL.', 'metasync'); | |
| 1478 | - } | |
| 1479 | - delete_transient('metasync_sitemap_robots_updated'); | |
| 1480 | - } | |
| 1481 | - | |
| 1482 | - echo '<div class="notice notice-success"><p>' . esc_html($message) . '</p></div>'; | |
| 1483 | - } | |
| 1484 | - } elseif (isset($_POST['enable_auto_update'])) { | |
| 1485 | - update_option('metasync_sitemap_auto_update', true); | |
| 1486 | - $sitemap_generator->setup_auto_update_hooks(); | |
| 1487 | - echo '<div class="notice notice-success"><p>' . esc_html__('Auto-update enabled!', 'metasync') . '</p></div>'; | |
| 1488 | - } elseif (isset($_POST['disable_auto_update'])) { | |
| 1489 | - update_option('metasync_sitemap_auto_update', false); | |
| 1490 | - echo '<div class="notice notice-success"><p>' . esc_html__('Auto-update disabled!', 'metasync') . '</p></div>'; | |
| 1491 | - } elseif (isset($_POST['delete_sitemap'])) { | |
| 1492 | - $deleted = $sitemap_generator->delete_sitemap(); | |
| 1493 | - if ($deleted) { | |
| 1494 | - update_option('metasync_sitemap_auto_update', false); | |
| 1495 | - // Re-enable WP core sitemap so the site isn't left with zero sitemaps | |
| 1496 | - delete_option('metasync_disable_wp_sitemap'); | |
| 1497 | - echo '<div class="notice notice-success"><p>' . esc_html__('Sitemap deleted successfully!', 'metasync') . '</p></div>'; | |
| 1498 | - } else { | |
| 1499 | - echo '<div class="notice notice-error"><p>' . esc_html__('Failed to delete sitemap. The file may not exist or is not writable.', 'metasync') . '</p></div>'; | |
| 1500 | - } | |
| 1501 | - } elseif (isset($_POST['enable_other_sitemaps'])) { | |
| 1502 | - $enabled_plugins = $sitemap_generator->enable_other_sitemap_generators(); | |
| 1503 | - if ($enabled_plugins) { | |
| 1504 | - echo '<div class="notice notice-success"><p>' . esc_html__('Other sitemap plugins have been re-enabled successfully!', 'metasync') . '</p></div>'; | |
| 1505 | - } else { | |
| 1506 | - echo '<div class="notice notice-info"><p>' . esc_html__('No sitemap plugins were found to re-enable.', 'metasync') . '</p></div>'; | |
| 1507 | - } | |
| 1508 | - } | |
| 1509 | - } | |
| 1510 | - | |
| 1511 | - $sitemap_exists = $sitemap_generator->sitemap_exists(); | |
| 1512 | - $sitemap_url = $sitemap_generator->get_sitemap_url(); | |
| 1513 | - $url_count = $sitemap_generator->count_urls(); | |
| 1514 | - $last_generated = $sitemap_generator->get_last_generated_time(); | |
| 1515 | - $auto_update_enabled = get_option('metasync_sitemap_auto_update', false); | |
| 1516 | - $active_sitemap_plugins = $sitemap_generator->check_active_sitemap_plugins(); | |
| 1517 | - | |
| 1518 | - require_once plugin_dir_path(dirname(__FILE__)) . 'views/metasync-xml-sitemap.php'; | |
| 1519 | 1450 | } |
| 1520 | 1451 | |
| 1521 | 1452 | public function create_admin_custom_pages_page() |
| 1522 | 1453 | { |