I made a hack.
Checks certain categories and in case of 404 error sends a message to the mail and re-saves the settings.
Initially I did it in the root directory and protected the file via .htaccess, but for some reason when running on cron the settings were not saved, although the script worked. Apparently something with the rights (didn’t figure it out).
I did it via a snippet. In this code, logging and sending a message after saving the settings are cut out. It works with a test 404 error, but I haven’t had a chance to check it with a real one yet.
// Adding a new interval for the cron (60 seconds)
add_filter('cron_schedules', function ($schedules) {
$schedules['60sec'] = array(
'interval' => 60,
'display' => __('Every 60 seconds'),
);
return $schedules;
});
// Schedule a cron event on initialization
add_action('init', function() {
if (!wp_next_scheduled('check_urls_cron_event')) {
wp_schedule_event(time(), '60sec', 'check_urls_cron_event');
}
});
// Cron event handler
add_action('check_urls_cron_event', function() {
// Список URL-адресов для проверки
$urls = [
'https://site.com/category/',
'https://site.com/category_1/',
'https://site.com/category_2/'
];
// Email, to which the notification will be sent
$to = '[email protected]';
// Letter subject
$subject = 'Subject 404';
// Function to check page status
function checkUrl($url) {
$headers = @get_headers($url);
if ($headers && strpos($headers[0], '404') !== false) {
return '404 Not Found';
}
return 'OK';
}
// We check all URLs and collect statuses
$statusMessages = [];
$has404Error = false;
foreach ($urls as $url) {
$status = checkUrl($url);
$statusMessages[] = "$url: $status";
if ($status === '404 Not Found') {
$has404Error = true;
}
}
// Execute script if 404 errors are found
if ($has404Error) {
// Executing the script
require_once(ABSPATH . 'wp-load.php');
// Checking if WordPress is loaded
if (function_exists('get_option')) {
// Get current permanent link settings
$current_permalink_structure = get_option('permalink_structure');
// New permanent link structure
$new_permalink_structure = '/%postname%/';
// Updating the structure of permanent links
$result = update_option('permalink_structure', $new_permalink_structure);
// Rewriting rewriting rules (rewrite rules)
global $wp_rewrite;
if (is_object($wp_rewrite) && method_exists($wp_rewrite, 'flush_rules')) {
$wp_rewrite->flush_rules();
}
// Send email after saving settings
$message = "The status of the checked URLs is as follows:\n\n" . implode("\n", $statusMessages);
mail($to, $subject, $message);
}
}
});