152 lines
4.6 KiB
PHP
152 lines
4.6 KiB
PHP
<?php
|
|
namespace RSSSL\Security\Includes\Check404;
|
|
|
|
class Rsssl_Test_404 {
|
|
// Static instance property
|
|
public static $instance = null;
|
|
|
|
// Private constructor to prevent direct instantiation
|
|
private function __construct() {
|
|
// Immediately check if there are resources to process and handle them
|
|
$resources = get_option( 'rsssl_404_resources_to_check' );
|
|
$found_404_option_value = get_option( 'rsssl_homepage_contains_404_resources', false );
|
|
$found_404s = $found_404_option_value === true || $found_404_option_value === "true";
|
|
|
|
if ( ! empty( $resources ) && ! $found_404s ) {
|
|
// Trigger chunk processing if resources are pending
|
|
$this->process_404_resources_chunk();
|
|
}
|
|
|
|
$this->fetch_and_check_homepage_resources();
|
|
|
|
}
|
|
|
|
// Static method to get the single instance of the class
|
|
public static function get_instance() {
|
|
if ( self::$instance === null ) {
|
|
self::$instance = new self();
|
|
}
|
|
|
|
return self::$instance;
|
|
}
|
|
|
|
// Process resources in chunks
|
|
public function process_404_resources_chunk() {
|
|
$resources = get_option( 'rsssl_404_resources_to_check' );
|
|
if ( empty( $resources ) ) {
|
|
update_option( 'rsssl_homepage_contains_404_resources', 'false' );
|
|
return false;
|
|
}
|
|
|
|
// Process a chunk of the resources (e.g., 2 at a time)
|
|
$chunk_size = 2;
|
|
$resources_chunk = array_splice( $resources, 0, $chunk_size );
|
|
|
|
$result = $this->process_404_resources( $resources_chunk );
|
|
|
|
// Update the remaining resources back to the option
|
|
if ( ! empty( $resources ) ) {
|
|
update_option( 'rsssl_404_resources_to_check', $resources );
|
|
return 'processing';
|
|
} else {
|
|
// All resources have been processed
|
|
return $result;
|
|
}
|
|
}
|
|
|
|
// Function to check homepage and handle 404s
|
|
public static function homepage_contains_404_resources() {
|
|
$found_404_option_value = get_option( 'rsssl_homepage_contains_404_resources', false );
|
|
if ( $found_404_option_value === true || $found_404_option_value === "true" ) {
|
|
return true;
|
|
}
|
|
|
|
$resources = get_option( 'rsssl_404_resources_to_check' );
|
|
if ( ! empty( $resources ) ) {
|
|
// If resources are available to check, process them immediately
|
|
return self::get_instance()->process_404_resources_chunk();
|
|
}
|
|
|
|
}
|
|
|
|
// Function to fetch homepage resources and check for 404 errors
|
|
public function fetch_and_check_homepage_resources() {
|
|
|
|
if ( get_option('rsssl_homepage_contains_404_resources') ) {
|
|
return;
|
|
}
|
|
|
|
$site_url = trailingslashit( home_url() );
|
|
|
|
$response = wp_remote_get( $site_url );
|
|
if ( is_wp_error( $response ) ) {
|
|
update_option( 'rsssl_homepage_contains_404_resources', false );
|
|
return false;
|
|
}
|
|
|
|
$status_code = wp_remote_retrieve_response_code( $response );
|
|
if ( $status_code == 404 ) {
|
|
update_option( 'rsssl_homepage_contains_404_resources', true );
|
|
return true;
|
|
}
|
|
|
|
// Patterns to match img, script, link tags
|
|
$body = wp_remote_retrieve_body( $response );
|
|
$patterns = array(
|
|
'/<img[^>]+src=([\'"])?((.*?)\1)/i',
|
|
'/<script[^>]+src=([\'"])?((.*?)\1)/i',
|
|
'/<link[^>]+href=([\'"])?((.*?)\1)/i'
|
|
);
|
|
|
|
$resources = array();
|
|
foreach ( $patterns as $pattern ) {
|
|
if ( preg_match_all( $pattern, $body, $matches ) ) {
|
|
foreach ( $matches[2] as $resource_url ) {
|
|
$resource_url = esc_url_raw( $resource_url );
|
|
if ( strpos( $resource_url, $site_url ) !== false ) {
|
|
$resources[] = $resource_url;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( count( $resources ) > 2 ) {
|
|
update_option( 'rsssl_404_resources_to_check', $resources );
|
|
return $this->process_404_resources_chunk();
|
|
} else {
|
|
if ( empty( $resources ) ) {
|
|
update_option( 'rsssl_homepage_contains_404_resources', 'false' );
|
|
return false;
|
|
}
|
|
|
|
update_option( 'rsssl_404_resources_to_check', $resources );
|
|
// Process all resources if fewer than 5
|
|
return $this->process_404_resources( $resources );
|
|
}
|
|
}
|
|
|
|
// Function to process a list of resources and check for 404 errors
|
|
private function process_404_resources( $resources ) {
|
|
$not_found_resources = array();
|
|
|
|
foreach ( $resources as $resource_url ) {
|
|
$resource_response = wp_remote_head( $resource_url );
|
|
if ( is_wp_error( $resource_response ) ) {
|
|
$not_found_resources[] = $resource_url . ' (Error: ' . $resource_response->get_error_message() . ')';
|
|
} else {
|
|
$resource_status = wp_remote_retrieve_response_code( $resource_response );
|
|
if ( $resource_status == 404 ) {
|
|
$not_found_resources[] = $resource_url;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( empty( $not_found_resources ) ) {
|
|
update_option( 'rsssl_homepage_contains_404_resources', 'false' );
|
|
return false;
|
|
} else {
|
|
update_option( 'rsssl_homepage_contains_404_resources', 'true' );
|
|
return true;
|
|
}
|
|
}
|
|
} |