oont-contents/plugins/wp-rocket/inc/Engine/Preload/Controller/PreloadUrl.php
2025-02-08 15:10:23 +01:00

240 lines
6.1 KiB
PHP

<?php
namespace WP_Rocket\Engine\Preload\Controller;
use WP_Rocket\Admin\Options_Data;
use WP_Rocket\Engine\Preload\Database\Queries\Cache;
use WP_Filesystem_Direct;
class PreloadUrl {
use CheckExcludedTrait;
/**
* Preload queue.
*
* @var Queue
*/
protected $queue;
/**
* Preload database query.
*
* @var Cache
*/
protected $query;
/**
* Configurations options.
*
* @var Options_Data
*/
protected $options;
/**
* Filesystem.
*
* @var WP_Filesystem_Direct
*/
protected $filesystem;
/**
* Instantiate preload controller.
*
* @param Options_Data $options configuration options.
* @param Queue $queue preload queue.
* @param Cache $rocket_cache preload database query.
* @param WP_Filesystem_Direct $filesystem Filesystem.
*/
public function __construct( Options_Data $options, Queue $queue, Cache $rocket_cache, WP_Filesystem_Direct $filesystem ) {
$this->options = $options;
$this->query = $rocket_cache;
$this->queue = $queue;
$this->filesystem = $filesystem;
}
/**
* Preload an url.
*
* @param string $url url to preload.
* @return void
*/
public function preload_url( string $url ) {
$is_mobile = $this->options->get( 'do_caching_mobile_files', false );
if ( $this->is_already_cached( $url ) && ( ! $is_mobile || $this->is_already_cached( $url, true ) ) ) {
$this->query->make_status_complete( $url );
return;
}
$requests = [
[
'url' => $url,
'is_mobile' => false,
'headers' => [
'blocking' => false,
'timeout' => 0.01,
'user-agent' => 'WP Rocket/Preload',
],
],
];
if ( $is_mobile ) {
$requests[] = [
'url' => $url,
'headers' => [
'user-agent' => $this->get_mobile_user_agent_prefix(),
],
'is_mobile' => true,
];
}
/**
* Filters to modify requests done to preload an url.
*
* @param array $requests Requests that will be done.
*/
$requests = apply_filters( 'rocket_preload_before_preload_url', $requests );
if ( ! is_array( $requests ) ) {
return;
}
$requests = array_filter( $requests );
foreach ( $requests as $request ) {
if ( ! isset( $request['url'] ) || ! is_string( $request['url'] ) ) {
continue;
}
$headers = isset( $request['headers'] ) && is_array( $request['headers'] ) ? $request['headers'] : [];
$headers = array_merge(
$headers,
[
'blocking' => false,
'timeout' => 0.01,
/**
* Filter to activate the verification of SSl.
*
* @param string $activate is the verification activated.
*/
'sslverify' => apply_filters( 'https_local_ssl_verify', false ), // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
]
);
/**
* Filters the arguments for the preload request.
*
* @param array $headers Request arguments.
*/
$headers = apply_filters(
'rocket_preload_url_request_args',
$headers
);
if ( ! is_array( $headers ) ) {
return;
}
wp_safe_remote_get(
user_trailingslashit( $request['url'] ),
$headers
);
/**
* Filter the delay between each preload request.
*
* @param float $delay_between the defined delay.
* @returns float
*/
$delay_between = apply_filters( 'rocket_preload_delay_between_requests', 500000 );
usleep( $delay_between );
}
}
/**
* Get the prefix to prepend to the user agent used for preload to make a HTTP request detected as a mobile device.
*
* @return string
*/
protected function get_mobile_user_agent_prefix() {
$prefix = 'Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1';
/**
* Filter the prefix to prepend to the user agent used for preload to make a HTTP request detected as a mobile device.
*
* @param string $prefix The prefix.
*/
$new_prefix = apply_filters( 'rocket_mobile_preload_user_agent_prefix', $prefix );
if ( empty( $new_prefix ) || ! is_string( $new_prefix ) ) {
return $prefix;
}
return $new_prefix;
}
/**
* Process pending jobs inside CRON iteration.
*
* @return void
*/
public function process_pending_jobs() {
$count = apply_filters( 'rocket_preload_cache_pending_jobs_cron_rows_count', 45 );
$rows = $this->query->get_pending_jobs( $count );
foreach ( $rows as $index => $row ) {
if ( $this->is_excluded_by_filter( $row->url ) ) {
$this->query->delete_by_url( $row->url );
continue;
}
$this->query->make_status_inprogress( $row->id );
$this->queue->add_job_preload_job_preload_url_async( $row->url );
}
}
/**
* Check if the cache file for $item already exists.
*
* @param string $url The URL to preload.
* @param bool $is_mobile is mobile text.
*
* @return bool
*/
public function is_already_cached( string $url, bool $is_mobile = false ) {
static $https;
if ( ! isset( $https ) ) {
$https = is_ssl() && $this->options->get( 'cache_ssl' ) ? '-https' : '';
}
$url = get_rocket_parse_url( $url );
/** This filter is documented in inc/functions/htaccess.php */
if ( apply_filters( 'rocket_url_no_dots', false ) ) {
$url['host'] = str_replace( '.', '_', $url['host'] );
}
$url['path'] = trailingslashit( $url['path'] );
if ( '' !== $url['query'] ) {
$url['query'] = '#' . $url['query'] . '/';
}
$mobile = $is_mobile ? '-mobile' : '';
$file_cache_path = rocket_get_constant( 'WP_ROCKET_CACHE_PATH' ) . $url['host'] . strtolower( $url['path'] . $url['query'] ) . 'index' . $mobile . $https . '.html';
if ( ! $this->options->get( 'cache_webp', false ) ) {
return $this->filesystem->exists( $file_cache_path );
}
$webp_path = rocket_get_constant( 'WP_ROCKET_CACHE_PATH' ) . $url['host'] . strtolower( $url['path'] . $url['query'] ) . 'index' . $mobile . $https . '-webp.html';
$no_webp_path = rocket_get_constant( 'WP_ROCKET_CACHE_PATH' ) . $url['host'] . strtolower( $url['path'] . $url['query'] ) . '.no-webp';
return $this->filesystem->exists( $webp_path ) || ( $this->filesystem->exists( $no_webp_path ) && $this->filesystem->exists( $file_cache_path ) );
}
}