add wp-rocket

This commit is contained in:
nguyen dung
2022-02-18 19:09:35 +07:00
parent 39b8cb3612
commit 3110d00ee7
927 changed files with 271703 additions and 2 deletions

View File

@@ -0,0 +1,457 @@
<?php
defined( 'ABSPATH' ) || exit;
/**
* This warning is displayed when the API KEY isn't already set or not valid
*
* @since 1.0
*/
function rocket_need_api_key() {
$message = '';
$errors = get_transient( 'rocket_check_key_errors' );
if ( false !== $errors ) {
foreach ( $errors as $error ) {
$message .= '<p>' . $error . '</p>';
}
}
?>
<div class="notice notice-error">
<p><strong><?php echo esc_html( WP_ROCKET_PLUGIN_NAME ); ?></strong>
<?php
echo esc_html( _n( 'There seems to be an issue validating your license. Please see the error message below.', 'There seems to be an issue validating your license. You can see the error messages below.', count( $errors ), 'rocket' ) );
?>
</p>
<?php echo wp_kses_post( $message ); ?>
</div>
<?php
}
/**
* Renew all boxes for everyone if $uid is missing
*
* @since 1.1.10
* @modified 2.1 :
* - Better usage of delete_user_meta into delete_metadata
*
* @param (int|null) $uid : a User id, can be null, null = all users.
* @param (string|array) $keep_this : which box have to be kept.
* @return void
*/
function rocket_renew_all_boxes( $uid = null, $keep_this = [] ) {
// Delete a user meta for 1 user or all at a time.
delete_metadata( 'user', $uid, 'rocket_boxes', null === $uid );
// $keep_this works only for the current user.
if ( ! empty( $keep_this ) && null !== $uid ) {
if ( ! is_array( $keep_this ) ) {
$keep_this = (array) $keep_this;
}
foreach ( $keep_this as $kt ) {
rocket_dismiss_box( $kt );
}
}
}
/**
* Renew a dismissed error box admin side
*
* @since 1.1.10
*
* @param string $function function name.
* @param int $uid User ID.
* @return void
*/
function rocket_renew_box( $function, $uid = 0 ) {
global $current_user;
$uid = 0 === $uid ? $current_user->ID : $uid;
$actual = get_user_meta( $uid, 'rocket_boxes', true );
if ( $actual && false !== array_search( $function, $actual, true ) ) {
unset( $actual[ array_search( $function, $actual, true ) ] );
update_user_meta( $uid, 'rocket_boxes', $actual );
}
}
/**
* Dismiss one box.
*
* @since 1.3.0
* @since 3.6 Doesnt die anymore.
*
* @param string $function Function (box) name.
*/
function rocket_dismiss_box( $function ) {
$actual = get_user_meta( get_current_user_id(), 'rocket_boxes', true );
$actual = array_merge( (array) $actual, [ $function ] );
$actual = array_filter( $actual );
$actual = array_unique( $actual );
update_user_meta( get_current_user_id(), 'rocket_boxes', $actual );
delete_transient( $function );
}
/**
* Create a unique id for some Rocket options and functions
*
* @since 2.1
*/
function create_rocket_uniqid() { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals
return str_replace( '.', '', uniqid( '', true ) );
}
/**
* Gets names of all active plugins.
*
* @since 2.11 Only get the name
* @since 2.6
*
* @return array An array of active plugins names.
*/
function rocket_get_active_plugins() {
$plugins = [];
$active_plugins = array_intersect_key( get_plugins(), array_flip( array_filter( array_keys( get_plugins() ), 'is_plugin_active' ) ) );
foreach ( $active_plugins as $plugin ) {
$plugins[] = $plugin['Name'];
}
return $plugins;
}
/**
* Check if the whole website is on the SSL protocol
*
* @since 3.3.6 Use the superglobal $_SERVER values to detect SSL.
* @since 2.7
*/
function rocket_is_ssl_website() {
if ( isset( $_SERVER['HTTPS'] ) ) {
$https = sanitize_text_field( wp_unslash( $_SERVER['HTTPS'] ) );
if ( 'on' === strtolower( $https ) ) {
return true;
}
if ( '1' === (string) $https ) {
return true;
}
} elseif ( isset( $_SERVER['SERVER_PORT'] ) && '443' === (string) sanitize_text_field( wp_unslash( $_SERVER['SERVER_PORT'] ) ) ) {
return true;
}
return false;
}
/**
* Get the WP Rocket documentation URL
*
* @since 2.7
*/
function get_rocket_documentation_url() { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals
$langs = [
'fr_FR' => 'fr.',
];
$lang = get_locale();
$prefix = isset( $langs[ $lang ] ) ? $langs[ $lang ] : '';
$url = "https://{$prefix}docs.wp-rocket.me/?utm_source=wp_plugin&utm_medium=wp_rocket";
return $url;
}
/**
* Get WP Rocket FAQ URL
*
* @since 2.10
* @author Remy Perona
*
* @return string URL in the correct language
*/
function get_rocket_faq_url() { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals
$langs = [
'de' => 1,
'es' => 1,
'fr' => 1,
'it' => 1,
];
$locale = explode( '_', get_locale() );
$lang = isset( $langs[ $locale[0] ] ) ? $locale[0] . '/' : '';
$url = WP_ROCKET_WEB_MAIN . "{$lang}faq/?utm_source=wp_plugin&utm_medium=wp_rocket";
return $url;
}
/**
* Get the Activation Link for a given plugin
*
* @since 2.7.3
* @author Geoffrey Crofte
*
* @param string $plugin the given plugin folder/file.php (e.i. "imagify/imagify.php").
* @return string URL to activate the plugin
*/
function rocket_get_plugin_activation_link( $plugin ) {
$activation_url = wp_nonce_url( 'plugins.php?action=activate&amp;plugin=' . $plugin . '&amp;plugin_status=all&amp;paged=1&amp;s', 'activate-plugin_' . $plugin );
return $activation_url;
}
/**
* Check if a given plugin is installed but not necessarily activated
* Note: get_plugins( $folder ) from WP Core doesn't work
*
* @since 2.7.3
* @author Geoffrey Crofte
*
* @param string $plugin a plugin folder/file.php (e.i. "imagify/imagify.php").
* @return bool True if installed, false otherwise
*/
function rocket_is_plugin_installed( $plugin ) {
$installed_plugins = get_plugins();
return isset( $installed_plugins[ $plugin ] );
}
/**
* When Woocommerce, EDD, iThemes Exchange, Jigoshop & WP-Shop options are saved or deleted,
* we update .htaccess & config file to get the right checkout page to exclude to the cache.
*
* @since 2.9.3 Support for SF Move Login moved to 3rd party file
* @since 2.6 Add support with SF Move Login & WPS Hide Login to exclude login pages
* @since 2.4
*
* @param array $old_value An array of previous settings values.
* @param array $value An array of submitted settings values.
*/
function rocket_after_update_single_options( $old_value, $value ) {
if ( $old_value !== $value ) {
// Update .htaccess file rules.
flush_rocket_htaccess();
// Update config file.
rocket_generate_config_file();
}
}
/**
* We need to regenerate the config file + htaccess depending on some plugins
*
* @since 2.9.3 Support for SF Move Login moved to 3rd party file
* @since 2.6.5 Add support with SF Move Login & WPS Hide Login
*
* @param array $old_value An array of previous settings values.
* @param array $value An array of submitted settings values.
*/
function rocket_after_update_array_options( $old_value, $value ) {
$options = [
'purchase_page',
'jigoshop_cart_page_id',
'jigoshop_checkout_page_id',
'jigoshop_myaccount_page_id',
];
foreach ( $options as $val ) {
if ( ( ! isset( $old_value[ $val ] ) && isset( $value[ $val ] ) ) ||
( isset( $old_value[ $val ], $value[ $val ] ) && $old_value[ $val ] !== $value[ $val ] )
) {
// Update .htaccess file rules.
flush_rocket_htaccess();
// Update config file.
rocket_generate_config_file();
break;
}
}
}
/**
* Check if a mobile plugin is active
*
* @since 2.10
* @author Remy Perona
*
* @return true if a mobile plugin in the list is active, false otherwise.
**/
function rocket_is_mobile_plugin_active() {
return \WP_Rocket\Subscriber\Third_Party\Plugins\Mobile_Subscriber::is_mobile_plugin_active();
}
/**
* Allow upload of JSON file.
*
* @since 2.10.7
* @author Remy Perona
*
* @param array $wp_get_mime_types Array of allowed mime types.
* @return array Updated array of allowed mime types
*/
function rocket_allow_json_mime_type( $wp_get_mime_types ) {
$wp_get_mime_types['json'] = 'application/json';
return $wp_get_mime_types;
}
/**
* Forces the correct file type for JSON file if the WP checks is incorrect
*
* @since 3.2.3.1
* @author Gregory Viguier
*
* @param array $wp_check_filetype_and_ext File data array containing 'ext', 'type', and
* 'proper_filename' keys.
* @param string $file Full path to the file.
* @param string $filename The name of the file (may differ from $file due to
* $file being in a tmp directory).
* @param array $mimes Key is the file extension with value as the mime type.
* @return array
*/
function rocket_check_json_filetype( $wp_check_filetype_and_ext, $file, $filename, $mimes ) {
if ( ! empty( $wp_check_filetype_and_ext['ext'] ) && ! empty( $wp_check_filetype_and_ext['type'] ) ) {
return $wp_check_filetype_and_ext;
}
$wp_filetype = wp_check_filetype( $filename, $mimes );
if ( 'json' !== $wp_filetype['ext'] ) {
return $wp_check_filetype_and_ext;
}
if ( empty( $wp_filetype['type'] ) ) {
// In case some other filter messed it up.
$wp_filetype['type'] = 'application/json';
}
if ( ! extension_loaded( 'fileinfo' ) ) {
return $wp_check_filetype_and_ext;
}
$finfo = finfo_open( FILEINFO_MIME_TYPE );
$real_mime = finfo_file( $finfo, $file );
finfo_close( $finfo );
if ( 'text/plain' !== $real_mime ) {
return $wp_check_filetype_and_ext;
}
$wp_check_filetype_and_ext = array_merge( $wp_check_filetype_and_ext, $wp_filetype );
return $wp_check_filetype_and_ext;
}
/**
* Lists Data collected for analytics
*
* @since 2.11
* @author Caspar Hübinger
*
* @return string HTML list table
*/
function rocket_data_collection_preview_table() {
$data = rocket_analytics_data();
if ( ! $data ) {
return;
}
$html = '<table class="wp-rocket-data-table widefat striped">';
$html .= '<tbody>';
$html .= '<tr>';
$html .= '<td class="column-primary">';
$html .= sprintf( '<strong>%s</strong>', __( 'Server type:', 'rocket' ) );
$html .= '</td>';
$html .= '<td>';
$html .= sprintf( '<code>%s</code>', $data['web_server'] );
$html .= '</td>';
$html .= '</tr>';
$html .= '<tr>';
$html .= '<td class="column-primary">';
$html .= sprintf( '<strong>%s</strong>', __( 'PHP version number:', 'rocket' ) );
$html .= '</td>';
$html .= '<td>';
$html .= sprintf( '<code>%s</code>', $data['php_version'] );
$html .= '</td>';
$html .= '</tr>';
$html .= '<tr>';
$html .= '<td class="column-primary">';
$html .= sprintf( '<strong>%s</strong>', __( 'WordPress version number:', 'rocket' ) );
$html .= '</td>';
$html .= '<td>';
$html .= sprintf( '<code>%s</code>', $data['wordpress_version'] );
$html .= '</td>';
$html .= '</tr>';
$html .= '<tr>';
$html .= '<td class="column-primary">';
$html .= sprintf( '<strong>%s</strong>', __( 'WordPress multisite:', 'rocket' ) );
$html .= '</td>';
$html .= '<td>';
$html .= sprintf( '<code>%s</code>', $data['multisite'] ? 'true' : 'false' );
$html .= '</td>';
$html .= '</tr>';
$html .= '<tr>';
$html .= '<td class="column-primary">';
$html .= sprintf( '<strong>%s</strong>', __( 'Current theme:', 'rocket' ) );
$html .= '</td>';
$html .= '<td>';
$html .= sprintf( '<code>%s</code>', $data['current_theme'] );
$html .= '</td>';
$html .= '</tr>';
$html .= '<tr>';
$html .= '<td class="column-primary">';
$html .= sprintf( '<strong>%s</strong>', __( 'Current site language:', 'rocket' ) );
$html .= '</td>';
$html .= '<td>';
$html .= sprintf( '<code>%s</code>', $data['locale'] );
$html .= '</td>';
$html .= '</tr>';
$html .= '<tr>';
$html .= '<td class="column-primary">';
$html .= sprintf( '<strong>%s</strong>', __( 'Active plugins:', 'rocket' ) );
$html .= '</td>';
$html .= '<td>';
$html .= sprintf( '<em>%s</em>', __( 'Plugin names of all active plugins', 'rocket' ) );
$html .= '</td>';
$html .= '</tr>';
$html .= '<tr>';
$html .= '<td class="column-primary">';
$html .= sprintf( '<strong>%s</strong>', __( 'Anonymized WP Rocket settings:', 'rocket' ) );
$html .= '</td>';
$html .= '<td>';
$html .= sprintf( '<em>%s</em>', __( 'Which WP Rocket settings are active', 'rocket' ) );
$html .= '</td>';
$html .= '</tr>';
$html .= '</tbody>';
$html .= '</table>';
return $html;
}
/**
* Adds error message after settings import and redirects.
*
* @since 3.0
* @author Remy Perona
*
* @param string $message Message to display in the error notice.
* @param string $status Status of the error.
* @return void
*/
function rocket_settings_import_redirect( $message, $status ) {
add_settings_error( 'general', 'settings_updated', $message, $status );
set_transient( 'settings_errors', get_settings_errors(), 30 );
$goback = add_query_arg( 'settings-updated', 'true', wp_get_referer() );
wp_safe_redirect( esc_url_raw( $goback ) );
die();
}

View File

@@ -0,0 +1,139 @@
<?php
/**
* Get an URL with one of CNAMES added in options
*
* @since 2.1
*
* @param string $url The URL to parse.
* @param array $zone (default: array( 'all' )). Deprecated.
* @return string
*/
function get_rocket_cdn_url( $url, $zone = [ 'all' ] ) { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals
$container = apply_filters( 'rocket_container', '' );
$cdn = $container->get( 'cdn' );
return $cdn->rewrite_url( $url );
}
/**
* Wrapper of get_rocket_cdn_url() and print result
*
* @since 2.1
*
* @param string $url The URL to parse.
* @param array $zone (default: array( 'all' )). Deprecated.
*/
function rocket_cdn_url( $url, $zone = [ 'all' ] ) {
echo esc_url( get_rocket_cdn_url( $url, $zone ) );
}
/**
* Get all CNAMES.
*
* @since 2.1
* @since 3.0 Don't check for WP Rocket CDN option activated to be able to use the function on Hosting with CDN auto-enabled.
*
* @param string $zone List of zones. Default is 'all'.
* @return array List of CNAMES
*/
function get_rocket_cdn_cnames( $zone = 'all' ) { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals
$hosts = [];
$cnames = get_rocket_option( 'cdn_cnames', [] );
if ( $cnames ) {
$cnames_zone = get_rocket_option( 'cdn_zone', [] );
$zone = (array) $zone;
foreach ( $cnames as $k => $_urls ) {
if ( ! in_array( $cnames_zone[ $k ], $zone, true ) ) {
continue;
}
$_urls = explode( ',', $_urls );
$_urls = array_map( 'trim', $_urls );
foreach ( $_urls as $url ) {
$hosts[] = $url;
}
}
}
/**
* Filter all CNAMES.
*
* @since 2.7
*
* @param array $hosts List of CNAMES.
*/
$hosts = (array) apply_filters( 'rocket_cdn_cnames', $hosts );
$hosts = array_filter( $hosts );
$hosts = array_flip( array_flip( $hosts ) );
$hosts = array_values( $hosts );
return $hosts;
}
/**
* Check if the current URL is for a live site (not local, not staging).
*
* @since 3.5
* @author Remy Perona
*
* @return bool True if live, false otherwise.
*/
function rocket_is_live_site() {
if ( rocket_get_constant( 'WP_ROCKET_DEBUG' ) ) {
return true;
}
$host = wp_parse_url( home_url(), PHP_URL_HOST );
if ( ! $host ) {
return false;
}
// Check for local development sites.
$local_tlds = [
'127.0.0.1',
'localhost',
'.local',
'.test',
'.docksal',
'.docksal.site',
'.dev.cc',
'.lndo.site',
];
foreach ( $local_tlds as $local_tld ) {
if ( $host === $local_tld ) {
return false;
}
// Check the TLD.
if ( substr( $host, -strlen( $local_tld ) ) === $local_tld ) {
return false;
}
}
// Check for staging sites.
$staging = [
'.wpengine.com',
'.pantheonsite.io',
'.flywheelsites.com',
'.flywheelstaging.com',
'.kinsta.com',
'.kinsta.cloud',
'.cloudwaysapps.com',
'.azurewebsites.net',
'.wpserveur.net',
'-liquidwebsites.com',
'.myftpupload.com',
'.dream.press',
];
foreach ( $staging as $partial_host ) {
if ( strpos( $host, $partial_host ) ) {
return false;
}
}
return true;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,570 @@
<?php
defined( 'ABSPATH' ) || exit;
/**
* Get relative url
* Clean URL file to get only the equivalent of REQUEST_URI
* ex: rocket_clean_exclude_file( 'http://www.geekpress.fr/referencement-wordpress/') return /referencement-wordpress/
*
* @since 1.3.5 Redo the function
* @since 1.0
*
* @param string $file URL we want to parse.
* @return bool\string false if $file is empty or false, relative path otherwise
*/
function rocket_clean_exclude_file( $file ) {
if ( ! $file ) {
return false;
}
return wp_parse_url( $file, PHP_URL_PATH );
}
/**
* Clean Never Cache URL(s) bad wildcards
*
* @since 3.4.2
* @author Soponar Cristina
*
* @param string $path URL which needs to be cleaned.
* @return bool\string false if $path is empty or cleaned URL
*/
function rocket_clean_wildcards( $path ) {
if ( ! $path ) {
return false;
}
$path_components = explode( '/', $path );
$arr = [
'.*' => '(.*)',
'*' => '(.*)',
'(*)' => '(.*)',
'(.*)' => '(.*)',
];
foreach ( $path_components as &$path_component ) {
$path_component = strtr( $path_component, $arr );
}
$path = implode( '/', $path_components );
return $path;
}
/**
* Used with array_filter to remove files without .css extension
*
* @since 1.0
*
* @param string $file filepath to sanitize.
* @return bool\string false if not a css file, filepath otherwise
*/
function rocket_sanitize_css( $file ) {
$file = preg_replace( '#\?.*$#', '', $file );
$ext = strtolower( pathinfo( $file, PATHINFO_EXTENSION ) );
return ( 'css' === $ext || 'php' === $ext ) ? trim( $file ) : false;
}
/**
* Used with array_filter to remove files without .js extension
*
* @since 1.0
*
* @param string $file filepath to sanitize.
* @return bool\string false if not a js file, filepath otherwise
*/
function rocket_sanitize_js( $file ) {
$file = preg_replace( '#\?.*$#', '', $file );
$ext = strtolower( pathinfo( $file, PATHINFO_EXTENSION ) );
return ( 'js' === $ext || 'php' === $ext ) ? trim( $file ) : false;
}
/**
* Sanitize and validate JS files to exclude from the minification.
*
* @since 3.3.7
* @author Remy Perona
* @author Grégory Viguier
*
* @param string $file filepath to sanitize.
* @return string
*/
function rocket_validate_js( $file ) {
if ( rocket_is_internal_file( $file ) ) {
$file = trim( $file );
$file = rocket_clean_exclude_file( $file );
$file = rocket_sanitize_js( $file );
return $file;
}
return sanitize_text_field( rocket_remove_url_protocol( strtok( $file, '?' ) ) );
}
/**
* Sanitize and validate CSS files to exclude from the minification.
*
* @since 3.7
*
* @param string $file filepath to sanitize.
* @return string
*/
function rocket_validate_css( $file ) {
if ( rocket_is_internal_file( $file ) ) {
return rocket_sanitize_css( rocket_clean_exclude_file( trim( $file ) ) );
}
return sanitize_text_field( rocket_remove_url_protocol( strtok( $file, '?' ) ) );
}
/**
* Check if the passed value is an internal URL (default domain or CDN/Multilingual).
*
* @since 3.3.7
* @author Remy Perona
* @author Grégory Viguier
*
* @param string $file string to test.
* @return bool
*/
function rocket_is_internal_file( $file ) {
$file_host = wp_parse_url( $file, PHP_URL_HOST );
if ( empty( $file_host ) ) {
return false;
}
/**
* Filters the allowed hosts for optimization
*
* @since 3.4
* @author Remy Perona
*
* @param array $hosts Allowed hosts.
* @param array $zones Zones to check available hosts.
*/
$hosts = apply_filters( 'rocket_cdn_hosts', [], [ 'all', 'css_and_js', 'css', 'js' ] );
$hosts[] = wp_parse_url( content_url(), PHP_URL_HOST );
$langs = get_rocket_i18n_uri();
// Get host for all langs.
if ( ! empty( $langs ) ) {
foreach ( $langs as $lang ) {
$hosts[] = wp_parse_url( $lang, PHP_URL_HOST );
}
}
$hosts = array_unique( $hosts );
if ( empty( $hosts ) ) {
return false;
}
return in_array( $file_host, $hosts, true );
}
/**
* Sanitize a setting value meant for a textarea.
*
* @since 3.3.7
* @author Grégory Viguier
*
* @param string $field The fields name. Can be one of the following:
* 'exclude_css', 'exclude_inline_js', 'exclude_js', 'cache_reject_uri',
* 'cache_reject_ua', 'cache_purge_pages', 'cdn_reject_files'.
* @param array|string $value The value to sanitize.
* @return array|null
*/
function rocket_sanitize_textarea_field( $field, $value ) {
$fields = [
'cache_purge_pages' => [ 'esc_url', 'rocket_clean_exclude_file', 'rocket_clean_wildcards' ], // Pattern.
'cache_reject_cookies' => [ 'rocket_sanitize_key' ],
'cache_reject_ua' => [ 'rocket_sanitize_ua', 'rocket_clean_wildcards' ], // Pattern.
'cache_reject_uri' => [ 'esc_url', 'rocket_clean_exclude_file', 'rocket_clean_wildcards' ], // Pattern.
'cache_query_strings' => [ 'rocket_sanitize_key' ],
'cdn_reject_files' => [ 'rocket_clean_exclude_file', 'rocket_clean_wildcards' ], // Pattern.
'exclude_css' => [ 'rocket_validate_css', 'rocket_clean_wildcards' ], // Pattern.
'exclude_inline_js' => [ 'sanitize_text_field' ], // Pattern.
'exclude_js' => [ 'rocket_validate_js', 'rocket_clean_wildcards' ], // Pattern.
'delay_js_scripts' => [ 'rocket_validate_js' ],
];
if ( ! isset( $fields[ $field ] ) ) {
return null;
}
$sanitizations = $fields[ $field ];
if ( ! is_array( $value ) ) {
$value = explode( "\n", $value );
}
$value = array_map( 'trim', $value );
$value = array_filter( $value );
if ( ! $value ) {
return [];
}
// Sanitize.
foreach ( $sanitizations as $sanitization ) {
$value = array_map( $sanitization, $value );
}
return array_unique( $value );
}
/**
* Used with array_filter to remove files without .xml extension
*
* @since 2.8
* @author Remy Perona
*
* @param string $file filepath to sanitize.
* @return string|boolean filename or false if not xml
*/
function rocket_sanitize_xml( $file ) {
$file = preg_replace( '#\?.*$#', '', $file );
$ext = strtolower( pathinfo( $file, PATHINFO_EXTENSION ) );
return ( 'xml' === $ext ) ? trim( $file ) : false;
}
/**
* Sanitizes a string key like the sanitize_key() WordPress function without forcing lowercase.
*
* @since 2.7
*
* @param string $key Key string to sanitize.
* @return string
*/
function rocket_sanitize_key( $key ) {
$key = preg_replace( '/[^a-z0-9_\-]/i', '', $key );
return $key;
}
/**
* Used to sanitize values of the "Never send cache pages for these user agents" option.
*
* @since 2.6.4
*
* @param string $user_agent User Agent string.
* @return string
*/
function rocket_sanitize_ua( $user_agent ) {
$user_agent = preg_replace( '/[^a-z0-9._\(\)\*\-\/\s\x5c]/i', '', $user_agent );
return $user_agent;
}
/**
* Get an url without HTTP protocol
*
* @since 1.3.0
*
* @param string $url The URL to parse.
* @param bool $no_dots (default: false).
* @return string $url The URL without protocol
*/
function rocket_remove_url_protocol( $url, $no_dots = false ) {
$url = preg_replace( '#^(https?:)?\/\/#im', '', $url );
/** This filter is documented in inc/front/htaccess.php */
if ( apply_filters( 'rocket_url_no_dots', $no_dots ) ) {
$url = str_replace( '.', '_', $url );
}
return $url;
}
/**
* Add HTTP protocol to an url that does not have it.
*
* @since 2.2.1
*
* @param string $url The URL to parse.
*
* @return string $url The URL with protocol.
*/
function rocket_add_url_protocol( $url ) {
// Bail out if the URL starts with http:// or https://.
if (
strpos( $url, 'http://' ) !== false
||
strpos( $url, 'https://' ) !== false
) {
return $url;
}
if ( substr( $url, 0, 2 ) !== '//' ) {
$url = '//' . $url;
}
return set_url_scheme( $url );
}
/**
* Set the scheme for a internal URL
*
* @since 2.6
*
* @param string $url Absolute url that includes a scheme.
* @return string $url URL with a scheme.
*/
function rocket_set_internal_url_scheme( $url ) {
$tmp_url = set_url_scheme( $url );
if ( rocket_extract_url_component( $tmp_url, PHP_URL_HOST ) === rocket_extract_url_component( home_url(), PHP_URL_HOST ) ) {
$url = $tmp_url;
}
return $url;
}
/**
* Get the domain of an URL without subdomain
* (ex: rocket_get_domain( 'http://www.geekpress.fr' ) return geekpress.fr
*
* @source : http://stackoverflow.com/a/15498686
* @since 2.7.3 undeprecated & updated
* @since 1.0
*
* @param string $url URL to parse.
* @return string|bool Domain or false
*/
function rocket_get_domain( $url ) {
// Add URL protocol if the $url doesn't have one to prevent issue with parse_url.
$url = rocket_add_url_protocol( trim( $url ) );
$url_array = wp_parse_url( $url );
$host = $url_array['host'];
/**
* Filters the tld max range for edge cases
*
* @since 2.7.3
*
* @param string Max range number
*/
$match = '/(?P<domain>[a-z0-9][a-z0-9\-]{1,63}\.[a-z\.]{2,' . apply_filters( 'rocket_get_domain_preg', '6' ) . '})$/i';
if ( preg_match( $match, $host, $regs ) ) {
return $regs['domain'];
}
return false;
}
/**
* Extract and return host, path, query and scheme of an URL
*
* @since 2.11.5 Supports UTF-8 URLs
* @since 2.1 Add $query variable
* @since 2.0
*
* @param string $url The URL to parse.
* @return array Components of an URL
*/
function get_rocket_parse_url( $url ) { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals
if ( ! is_string( $url ) ) {
return;
}
$encoded_url = preg_replace_callback(
'%[^:/@?&=#]+%usD',
function ( $matches ) {
return rawurlencode( $matches[0] );
},
$url
);
$url = wp_parse_url( $encoded_url );
$host = isset( $url['host'] ) ? strtolower( urldecode( $url['host'] ) ) : '';
$path = isset( $url['path'] ) ? urldecode( $url['path'] ) : '';
$scheme = isset( $url['scheme'] ) ? urldecode( $url['scheme'] ) : '';
$query = isset( $url['query'] ) ? urldecode( $url['query'] ) : '';
$fragment = isset( $url['fragment'] ) ? urldecode( $url['fragment'] ) : '';
/**
* Filter components of an URL
*
* @since 2.2
*
* @param array Components of an URL
*/
return (array) apply_filters(
'rocket_parse_url',
[
'host' => $host,
'path' => $path,
'scheme' => $scheme,
'query' => $query,
'fragment' => $fragment,
]
);
}
/**
* Extract a component from an URL.
*
* @since 2.11
* @author Remy Perona
*
* @param string $url URL to parse and extract component of.
* @param string $component URL component to extract using constant as in parse_url().
* @return string extracted component
*/
function rocket_extract_url_component( $url, $component ) {
return _get_component_from_parsed_url_array( wp_parse_url( $url ), $component );
}
/**
* Returns realpath to file (used for relative path with /../ in it or not-yet existing file)
*
* @since 2.11
* @author Remy Perona
*
* @param string $file File to determine realpath for.
* @return string Resolved file path
*/
function rocket_realpath( $file ) {
$wrapper = null;
// Strip the protocol.
if ( rocket_is_stream( $file ) ) {
list( $wrapper, $file ) = explode( '://', $file, 2 );
}
$path = [];
foreach ( explode( '/', $file ) as $part ) {
if ( '' === $part || '.' === $part ) {
continue;
}
if ( '..' !== $part ) {
array_push( $path, $part );
}
elseif ( count( $path ) > 0 ) {
array_pop( $path );
}
}
$file = join( '/', $path );
if ( null !== $wrapper ) {
return $wrapper . '://' . $file;
}
$prefix = 'WIN' === strtoupper( substr( PHP_OS, 0, 3 ) ) ? '' : '/';
return $prefix . $file;
}
/**
* Converts an URL to an absolute path.
*
* @since 2.11.7
* @author Remy Perona
*
* @param string $url URL to convert.
* @param array $zones Zones to check available hosts.
* @return string|bool
*/
function rocket_url_to_path( $url, array $zones = [ 'all' ] ) {
$wp_content_dir = rocket_get_constant( 'WP_CONTENT_DIR' );
$root_dir = trailingslashit( dirname( $wp_content_dir ) );
$root_url = str_replace( wp_basename( $wp_content_dir ), '', content_url() );
$url_host = wp_parse_url( $url, PHP_URL_HOST );
// relative path.
if ( null === $url_host ) {
$subdir_levels = substr_count( preg_replace( '/https?:\/\//', '', site_url() ), '/' );
$url = trailingslashit( site_url() . str_repeat( '/..', $subdir_levels ) ) . ltrim( $url, '/' );
}
/**
* Filters the URL before converting it to a path
*
* @since 3.5.3
* @author Remy Perona
*
* @param string $url URL of the asset.
* @param array $zones CDN zones corresponding to the current assets type.
*/
$url = apply_filters( 'rocket_asset_url', $url, $zones );
$url = rawurldecode( $url );
$root_url = preg_replace( '/^https?:/', '', $root_url );
$url = preg_replace( '/^https?:/', '', $url );
$file = str_replace( $root_url, $root_dir, $url );
$file = rocket_realpath( $file );
/**
* Filters the absolute path to the asset file
*
* @since 3.3
* @author Remy Perona
*
* @param string $file Absolute path to the file.
* @param string $url URL of the asset.
*/
$file = apply_filters( 'rocket_url_to_path', $file, $url );
if ( ! rocket_direct_filesystem()->is_readable( $file ) ) {
return false;
}
return $file;
}
/**
* Simple helper to get some external URLs.
*
* @since 2.10.10
* @author Grégory Viguier
*
* @param string $target What we want.
* @param array $query_args An array of query arguments.
* @return string The URL.
*/
function rocket_get_external_url( $target, $query_args = [] ) {
$site_url = WP_ROCKET_WEB_MAIN;
switch ( $target ) {
case 'support':
$locale = function_exists( 'get_user_locale' ) ? get_user_locale() : get_locale();
$paths = [
'default' => 'support',
'fr_FR' => 'fr/support',
'fr_CA' => 'fr/support',
'it_IT' => 'it/supporto',
'de_DE' => 'de/support',
'es_ES' => 'es/soporte',
];
$url = isset( $paths[ $locale ] ) ? $paths[ $locale ] : $paths['default'];
$url = $site_url . $url . '/';
break;
case 'account':
$locale = function_exists( 'get_user_locale' ) ? get_user_locale() : get_locale();
$paths = [
'default' => 'account',
'fr_FR' => 'fr/compte',
'fr_CA' => 'fr/compte',
'it_IT' => 'it/account/',
'de_DE' => 'de/konto/',
'es_ES' => 'es/cuenta/',
];
$url = isset( $paths[ $locale ] ) ? $paths[ $locale ] : $paths['default'];
$url = $site_url . $url . '/';
break;
default:
$url = $site_url;
}
if ( $query_args ) {
$url = add_query_arg( $query_args, $url );
}
return $url;
}

View File

@@ -0,0 +1,696 @@
<?php
defined( 'ABSPATH' ) || exit;
/**
* Used to flush the .htaccess file.
*
* @since 1.0
* @since 1.1.0 Remove empty spacings when .htaccess is generated.
*
* @param bool $remove_rules True to remove WPR rules, false to renew them. Default is false.
* @return bool True on success, false otherwise.
*/
function flush_rocket_htaccess( $remove_rules = false ) { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals
global $is_apache;
/**
* Filters disabling of WP Rocket htaccess rules
*
* @since 3.2.5
* @author Remy Perona
*
* @param bool $disable True to disable, false otherwise.
*/
if ( ! $is_apache || ( apply_filters( 'rocket_disable_htaccess', false ) && ! $remove_rules ) ) {
return false;
}
if ( ! function_exists( 'get_home_path' ) ) {
require_once ABSPATH . 'wp-admin/includes/file.php';
}
$htaccess_file = get_home_path() . '.htaccess';
if ( ! rocket_direct_filesystem()->is_writable( $htaccess_file ) ) {
// The file is not writable or does not exist.
return false;
}
// Get content of .htaccess file.
$ftmp = rocket_direct_filesystem()->get_contents( $htaccess_file );
if ( false === $ftmp ) {
// Could not get the file contents.
return false;
}
// Check if the file contains the WP rules, before modifying anything.
$has_wp_rules = rocket_has_wp_htaccess_rules( $ftmp );
// Remove the WP Rocket marker.
$ftmp = preg_replace( '/\s*# BEGIN WP Rocket.*# END WP Rocket\s*?/isU', PHP_EOL . PHP_EOL, $ftmp );
$ftmp = ltrim( $ftmp );
if ( ! $remove_rules ) {
$ftmp = get_rocket_htaccess_marker() . PHP_EOL . $ftmp;
}
/**
* Determine if empty lines should be removed in the .htaccess file.
*
* @since 2.10.7
* @author Remy Perona
*
* @param boolean $remove_empty_lines True to remove, false otherwise.
*/
if ( apply_filters( 'rocket_remove_empty_lines', true ) ) {
$ftmp = preg_replace( "/\n+/", "\n", $ftmp );
}
// Make sure the WP rules are still there.
if ( $has_wp_rules && ! rocket_has_wp_htaccess_rules( $ftmp ) ) {
return false;
}
// Update the .htacces file.
return rocket_put_content( $htaccess_file, $ftmp );
}
/**
* Test if a server error is triggered by our rules
*
* @since 2.10
* @author Remy Perona
*
* @param (string) $rules_name The rules block to test.
*
* @return (object|bool) Return true if the server does not trigger an error 500, false otherwise.
* Return a WP_Error object if the sandbox creation fails or if the HTTP request fails.
*/
function rocket_htaccess_rules_test( $rules_name ) {
/**
* Filters the request arguments
*
* @author Remy Perona
* @since 2.10
*
* @param array $args Array of argument for the request.
*/
$request_args = apply_filters(
'rocket_htaccess_rules_test_args',
[
'redirection' => 0,
'timeout' => 5,
'sslverify' => apply_filters( 'https_local_ssl_verify', false ), // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals
'user-agent' => 'wprocketbot',
'cookies' => $_COOKIE,
]
);
$response = wp_remote_get( site_url( WP_ROCKET_URL . 'tests/' . $rules_name . '/index.html' ), $request_args );
if ( is_wp_error( $response ) ) {
return $response;
}
return 500 !== wp_remote_retrieve_response_code( $response );
}
/**
* Return the markers for htacces rules
*
* @since 1.0
*
* @return string $marker Rules that will be printed
*/
function get_rocket_htaccess_marker() { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals
// Recreate WP Rocket marker.
$marker = '# BEGIN WP Rocket v' . WP_ROCKET_VERSION . PHP_EOL;
/**
* Add custom rules before rules added by WP Rocket
*
* @since 2.6
*
* @param string $before_marker The content of all rules.
*/
$marker .= apply_filters( 'before_rocket_htaccess_rules', '' ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals
$marker .= get_rocket_htaccess_charset();
$marker .= get_rocket_htaccess_etag();
$marker .= get_rocket_htaccess_web_fonts_access();
$marker .= get_rocket_htaccess_files_match();
$marker .= get_rocket_htaccess_mod_expires();
$marker .= get_rocket_htaccess_mod_deflate();
if ( \WP_Rocket\Buffer\Cache::can_generate_caching_files() && ! is_rocket_generate_caching_mobile_files() ) {
$marker .= get_rocket_htaccess_mod_rewrite();
}
/**
* Add custom rules after rules added by WP Rocket
*
* @since 2.6
*
* @param string $after_marker The content of all rules.
*/
$marker .= apply_filters( 'after_rocket_htaccess_rules', '' ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals
$marker .= '# END WP Rocket' . PHP_EOL;
/**
* Filter rules added by WP Rocket in .htaccess
*
* @since 2.1
*
* @param string $marker The content of all rules.
*/
$marker = apply_filters( 'rocket_htaccess_marker', $marker );
return $marker;
}
/**
* Rewrite rules to serve the cache file
*
* @since 1.0
*
* @return string $rules Rules that will be printed
*/
function get_rocket_htaccess_mod_rewrite() { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals
// No rewrite rules for multisite.
if ( is_multisite() ) {
return;
}
// No rewrite rules for Korean.
if ( defined( 'WPLANG' ) && 'ko_KR' === WPLANG || 'ko_KR' === get_locale() ) {
return;
}
// Get root base.
$home_root = rocket_extract_url_component( home_url(), PHP_URL_PATH );
$home_root = isset( $home_root ) ? trailingslashit( $home_root ) : '/';
$site_root = rocket_extract_url_component( site_url(), PHP_URL_PATH );
$site_root = isset( $site_root ) ? trailingslashit( $site_root ) : '';
// Get cache root.
if ( strpos( ABSPATH, WP_ROCKET_CACHE_PATH ) === false && isset( $_SERVER['DOCUMENT_ROOT'] ) ) {
$cache_root = str_replace( sanitize_text_field( wp_unslash( $_SERVER['DOCUMENT_ROOT'] ) ), '', WP_ROCKET_CACHE_PATH );
} else {
$cache_root = $site_root . str_replace( ABSPATH, '', WP_ROCKET_CACHE_PATH );
}
/**
* Replace the dots by underscores to avoid some bugs on some shared hosting services on filenames (not multisite compatible!)
*
* @since 1.3.0
*
* @param bool true will replace the . by _.
*/
$http_host = apply_filters( 'rocket_url_no_dots', false ) ? rocket_remove_url_protocol( home_url() ) : '%{HTTP_HOST}';
/**
* Allow the path to be fully printed or dependant od %DOCUMENT_ROOT (forced for 1&1 by default)
*
* @since 1.3.0
*
* @param bool true will force the path to be full.
*/
$is_1and1_or_force = apply_filters( 'rocket_force_full_path', strpos( sanitize_text_field( wp_unslash( $_SERVER['DOCUMENT_ROOT'] ) ), '/kunden/' ) === 0 );
$rules = '';
$gzip_rules = '';
$enc = '';
if ( $is_1and1_or_force ) {
$cache_dir_path = str_replace( '/kunden/', '/', WP_ROCKET_CACHE_PATH ) . $http_host . '%{REQUEST_URI}';
} else {
$cache_dir_path = '%{DOCUMENT_ROOT}/' . ltrim( $cache_root, '/' ) . $http_host . '%{REQUEST_URI}';
}
// @codingStandardsIgnoreStart
/**
* Allow to serve gzip cache file
*
* @since 2.4
*
* @param bool true will force to serve gzip cache file.
*/
if ( function_exists( 'gzencode' ) && apply_filters( 'rocket_force_gzip_htaccess_rules', true ) ) {
$rules = '<IfModule mod_mime.c>' . PHP_EOL;
$rules .= 'AddType text/html .html_gzip' . PHP_EOL;
$rules .= 'AddEncoding gzip .html_gzip' . PHP_EOL;
$rules .= '</IfModule>' . PHP_EOL;
$rules .= '<IfModule mod_setenvif.c>' . PHP_EOL;
$rules .= 'SetEnvIfNoCase Request_URI \.html_gzip$ no-gzip' . PHP_EOL;
$rules .= '</IfModule>' . PHP_EOL . PHP_EOL;
$gzip_rules .= 'RewriteCond %{HTTP:Accept-Encoding} gzip' . PHP_EOL;
$gzip_rules .= 'RewriteRule .* - [E=WPR_ENC:_gzip]' . PHP_EOL;
$enc = '%{ENV:WPR_ENC}';
}
$rules .= '<IfModule mod_rewrite.c>' . PHP_EOL;
$rules .= 'RewriteEngine On' . PHP_EOL;
$rules .= 'RewriteBase ' . $home_root . PHP_EOL;
$rules .= get_rocket_htaccess_ssl_rewritecond();
$rules .= rocket_get_webp_rewritecond( $cache_dir_path );
$rules .= $gzip_rules;
$rules .= 'RewriteCond %{REQUEST_METHOD} GET' . PHP_EOL;
$rules .= 'RewriteCond %{QUERY_STRING} =""' . PHP_EOL;
$cookies = get_rocket_cache_reject_cookies();
if ( $cookies ) {
$rules .= 'RewriteCond %{HTTP:Cookie} !(' . $cookies . ') [NC]' . PHP_EOL;
}
$uri = get_rocket_cache_reject_uri();
if ( $uri ) {
$rules .= 'RewriteCond %{REQUEST_URI} !^(' . $uri . ')$ [NC]' . PHP_EOL;
}
$rules .= ! is_rocket_cache_mobile() ? get_rocket_htaccess_mobile_rewritecond() : '';
$ua = get_rocket_cache_reject_ua();
if ( $ua ) {
$rules .= 'RewriteCond %{HTTP_USER_AGENT} !^(' . $ua . ').* [NC]' . PHP_EOL;
}
$rules .= 'RewriteCond "' . $cache_dir_path . '/index%{ENV:WPR_SSL}%{ENV:WPR_WEBP}.html' . $enc . '" -f' . PHP_EOL;
$rules .= 'RewriteRule .* "' . $cache_root . $http_host . '%{REQUEST_URI}/index%{ENV:WPR_SSL}%{ENV:WPR_WEBP}.html' . $enc . '" [L]' . PHP_EOL;
$rules .= '</IfModule>' . PHP_EOL;
/**
* Filter rewrite rules to serve the cache file
*
* @since 1.0
*
* @param string $rules Rules that will be printed.
*/
$rules = apply_filters( 'rocket_htaccess_mod_rewrite', $rules );
return $rules;
}
/**
* Rules for detect mobile version
*
* @since 1.0
*
* @return string $rules Rules that will be printed
*/
function get_rocket_htaccess_mobile_rewritecond() { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals
// No rewrite rules for multisite.
if ( is_multisite() ) {
return;
}
$rules = 'RewriteCond %{HTTP:X-Wap-Profile} !^[a-z0-9\"]+ [NC]' . PHP_EOL;
$rules .= 'RewriteCond %{HTTP:Profile} !^[a-z0-9\"]+ [NC]' . PHP_EOL;
$rules .= 'RewriteCond %{HTTP_USER_AGENT} !^.*(2.0\ MMP|240x320|400X240|AvantGo|BlackBerry|Blazer|Cellphone|Danger|DoCoMo|Elaine/3.0|EudoraWeb|Googlebot-Mobile|hiptop|IEMobile|KYOCERA/WX310K|LG/U990|MIDP-2.|MMEF20|MOT-V|NetFront|Newt|Nintendo\ Wii|Nitro|Nokia|Opera\ Mini|Palm|PlayStation\ Portable|portalmmm|Proxinet|ProxiNet|SHARP-TQ-GX10|SHG-i900|Small|SonyEricsson|Symbian\ OS|SymbianOS|TS21i-10|UP.Browser|UP.Link|webOS|Windows\ CE|WinWAP|YahooSeeker/M1A1-R2D2|iPhone|iPod|Android|BlackBerry9530|LG-TU915\ Obigo|LGE\ VX|webOS|Nokia5800).* [NC]' . PHP_EOL;
$rules .= 'RewriteCond %{HTTP_USER_AGENT} !^(w3c\ |w3c-|acs-|alav|alca|amoi|audi|avan|benq|bird|blac|blaz|brew|cell|cldc|cmd-|dang|doco|eric|hipt|htc_|inno|ipaq|ipod|jigs|kddi|keji|leno|lg-c|lg-d|lg-g|lge-|lg/u|maui|maxo|midp|mits|mmef|mobi|mot-|moto|mwbp|nec-|newt|noki|palm|pana|pant|phil|play|port|prox|qwap|sage|sams|sany|sch-|sec-|send|seri|sgh-|shar|sie-|siem|smal|smar|sony|sph-|symb|t-mo|teli|tim-|tosh|tsm-|upg1|upsi|vk-v|voda|wap-|wapa|wapi|wapp|wapr|webc|winw|winw|xda\ |xda-).* [NC]' . PHP_EOL;
/**
* Filter rules for detect mobile version
*
* @since 2.0
*
* @param string $rules Rules that will be printed.
*/
$rules = apply_filters( 'rocket_htaccess_mobile_rewritecond', $rules );
return $rules;
}
/**
* Rules for SSL requests
*
* @since 2.7 Added rewrite condition for `%{HTTP:X-Forwarded-Proto}`.
* @since 2.0
*
* @return string $rules Rules that will be printed
*/
function get_rocket_htaccess_ssl_rewritecond() { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals
$rules = 'RewriteCond %{HTTPS} on [OR]' . PHP_EOL;
$rules .= 'RewriteCond %{SERVER_PORT} ^443$ [OR]' . PHP_EOL;
$rules .= 'RewriteCond %{HTTP:X-Forwarded-Proto} https' . PHP_EOL;
$rules .= 'RewriteRule .* - [E=WPR_SSL:-https]' . PHP_EOL;
/**
* Filter rules for SSL requests
*
* @since 2.0
*
* @param string $rules Rules that will be printed.
*/
$rules = apply_filters( 'rocket_htaccess_ssl_rewritecond', $rules );
return $rules;
}
/**
* Rules for webp compatible browsers.
*
* @since 3.4
* @author Grégory Viguier
*
* @param string $cache_dir_path Path to the cache directory, without trailing slash.
* @return string Rules that will be printed.
*/
function rocket_get_webp_rewritecond( $cache_dir_path ) {
if ( ! get_rocket_option( 'cache_webp' ) ) {
return '';
}
$rules = 'RewriteCond %{HTTP_ACCEPT} image/webp' . PHP_EOL;
$rules .= 'RewriteCond "' . $cache_dir_path . '/.no-webp" !-f' . PHP_EOL;
$rules .= 'RewriteRule .* - [E=WPR_WEBP:-webp]' . PHP_EOL;
/**
* Filter rules for webp.
*
* @since 3.4
* @author Grégory Viguier
*
* @param string $rules Rules that will be printed.
*/
return apply_filters( 'rocket_webp_rewritecond', $rules );
}
/**
* Rules to improve performances with GZIP Compression
*
* @since 1.0
*
* @return string $rules Rules that will be printed
*/
function get_rocket_htaccess_mod_deflate() { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals
$rules = '# Gzip compression' . PHP_EOL;
$rules .= '<IfModule mod_deflate.c>' . PHP_EOL;
$rules .= '# Active compression' . PHP_EOL;
$rules .= 'SetOutputFilter DEFLATE' . PHP_EOL;
$rules .= '# Force deflate for mangled headers' . PHP_EOL;
$rules .= '<IfModule mod_setenvif.c>' . PHP_EOL;
$rules .= '<IfModule mod_headers.c>' . PHP_EOL;
$rules .= 'SetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding|X{15}|~{15}|-{15})$ ^((gzip|deflate)\s*,?\s*)+|[X~-]{4,13}$ HAVE_Accept-Encoding' . PHP_EOL;
$rules .= 'RequestHeader append Accept-Encoding "gzip,deflate" env=HAVE_Accept-Encoding' . PHP_EOL;
$rules .= '# Dont compress images and other uncompressible content' . PHP_EOL;
$rules .= 'SetEnvIfNoCase Request_URI \\' . PHP_EOL;
$rules .= '\\.(?:gif|jpe?g|png|rar|zip|exe|flv|mov|wma|mp3|avi|swf|mp?g|mp4|webm|webp|pdf)$ no-gzip dont-vary' . PHP_EOL;
$rules .= '</IfModule>' . PHP_EOL;
$rules .= '</IfModule>' . PHP_EOL . PHP_EOL;
$rules .= '# Compress all output labeled with one of the following MIME-types' . PHP_EOL;
$rules .= '<IfModule mod_filter.c>' . PHP_EOL;
$rules .= 'AddOutputFilterByType DEFLATE application/atom+xml \
application/javascript \
application/json \
application/rss+xml \
application/vnd.ms-fontobject \
application/x-font-ttf \
application/xhtml+xml \
application/xml \
font/opentype \
image/svg+xml \
image/x-icon \
text/css \
text/html \
text/plain \
text/x-component \
text/xml' . PHP_EOL;
$rules .= '</IfModule>' . PHP_EOL;
$rules .= '<IfModule mod_headers.c>' . PHP_EOL;
$rules .= 'Header append Vary: Accept-Encoding' . PHP_EOL;
$rules .= '</IfModule>' . PHP_EOL;
$rules .= '</IfModule>' . PHP_EOL . PHP_EOL;
/**
* Filter rules to improve performances with GZIP Compression
*
* @since 1.0
*
* @param string $rules Rules that will be printed.
*/
$rules = apply_filters( 'rocket_htaccess_mod_deflate', $rules );
return $rules;
}
/**
* Rules to improve performances with Expires Headers
*
* @since 1.0
*
* @return string $rules Rules that will be printed
*/
function get_rocket_htaccess_mod_expires() { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals
$rules = <<<HTACCESS
# Expires headers (for better cache control)
<IfModule mod_expires.c>
ExpiresActive on
ExpiresDefault "access plus 1 month"
# cache.appcache needs re-requests in FF 3.6 (thanks Remy ~Introducing HTML5)
ExpiresByType text/cache-manifest "access plus 0 seconds"
# Your document html
ExpiresByType text/html "access plus 0 seconds"
# Data
ExpiresByType text/xml "access plus 0 seconds"
ExpiresByType application/xml "access plus 0 seconds"
ExpiresByType application/json "access plus 0 seconds"
# Feed
ExpiresByType application/rss+xml "access plus 1 hour"
ExpiresByType application/atom+xml "access plus 1 hour"
# Favicon (cannot be renamed)
ExpiresByType image/x-icon "access plus 1 week"
# Media: images, video, audio
ExpiresByType image/gif "access plus 4 months"
ExpiresByType image/png "access plus 4 months"
ExpiresByType image/jpeg "access plus 4 months"
ExpiresByType image/webp "access plus 4 months"
ExpiresByType video/ogg "access plus 4 months"
ExpiresByType audio/ogg "access plus 4 months"
ExpiresByType video/mp4 "access plus 4 months"
ExpiresByType video/webm "access plus 4 months"
# HTC files (css3pie)
ExpiresByType text/x-component "access plus 1 month"
# Webfonts
ExpiresByType font/ttf "access plus 4 months"
ExpiresByType font/otf "access plus 4 months"
ExpiresByType font/woff "access plus 4 months"
ExpiresByType font/woff2 "access plus 4 months"
ExpiresByType image/svg+xml "access plus 1 month"
ExpiresByType application/vnd.ms-fontobject "access plus 1 month"
# CSS and JavaScript
ExpiresByType text/css "access plus 1 year"
ExpiresByType application/javascript "access plus 1 year"
</IfModule>
HTACCESS;
/**
* Filter rules to improve performances with Expires Headers
*
* @since 1.0
*
* @param string $rules Rules that will be printed.
*/
$rules = apply_filters( 'rocket_htaccess_mod_expires', $rules );
return $rules;
}
/**
* Rules for default charset on static files
*
* @since 1.0
*
* @return string $rules Rules that will be printed
*/
function get_rocket_htaccess_charset() { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals
// Get charset of the blog.
$charset = preg_replace( '/[^a-zA-Z0-9_\-\.:]+/', '', get_bloginfo( 'charset', 'display' ) );
$rules = "# Use $charset encoding for anything served text/plain or text/html" . PHP_EOL;
$rules .= "AddDefaultCharset $charset" . PHP_EOL;
$rules .= "# Force $charset for a number of file formats" . PHP_EOL;
$rules .= '<IfModule mod_mime.c>' . PHP_EOL;
$rules .= "AddCharset $charset .atom .css .js .json .rss .vtt .xml" . PHP_EOL;
$rules .= '</IfModule>' . PHP_EOL . PHP_EOL;
/**
* Filter rules for default charset on static files
*
* @since 1.0
*
* @param string $rules Rules that will be printed.
*/
$rules = apply_filters( 'rocket_htaccess_charset', $rules );
return $rules;
}
/**
* Rules for cache control
*
* @since 1.1.6
*
* @return string $rules Rules that will be printed
*/
function get_rocket_htaccess_files_match() { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals
$rules = '<IfModule mod_alias.c>' . PHP_EOL;
$rules .= '<FilesMatch "\.(html|htm|rtf|rtx|txt|xsd|xsl|xml)$">' . PHP_EOL;
$rules .= '<IfModule mod_headers.c>' . PHP_EOL;
$rules .= 'Header set X-Powered-By "WP Rocket/' . WP_ROCKET_VERSION . '"' . PHP_EOL;
$rules .= 'Header unset Pragma' . PHP_EOL;
$rules .= 'Header append Cache-Control "public"' . PHP_EOL;
$rules .= 'Header unset Last-Modified' . PHP_EOL;
$rules .= '</IfModule>' . PHP_EOL;
$rules .= '</FilesMatch>' . PHP_EOL . PHP_EOL;
$rules .= '<FilesMatch "\.(css|htc|js|asf|asx|wax|wmv|wmx|avi|bmp|class|divx|doc|docx|eot|exe|gif|gz|gzip|ico|jpg|jpeg|jpe|json|mdb|mid|midi|mov|qt|mp3|m4a|mp4|m4v|mpeg|mpg|mpe|mpp|otf|odb|odc|odf|odg|odp|ods|odt|ogg|pdf|png|pot|pps|ppt|pptx|ra|ram|svg|svgz|swf|tar|tif|tiff|ttf|ttc|wav|wma|wri|xla|xls|xlsx|xlt|xlw|zip)$">' . PHP_EOL;
$rules .= '<IfModule mod_headers.c>' . PHP_EOL;
$rules .= 'Header unset Pragma' . PHP_EOL;
$rules .= 'Header append Cache-Control "public"' . PHP_EOL;
$rules .= '</IfModule>' . PHP_EOL;
$rules .= '</FilesMatch>' . PHP_EOL;
$rules .= '</IfModule>' . PHP_EOL . PHP_EOL;
/**
* Filter rules for cache control
*
* @since 1.1.6
*
* @param string $rules Rules that will be printed.
*/
$rules = apply_filters( 'rocket_htaccess_files_match', $rules );
return $rules;
}
/**
* Rules to remove the etag
*
* @since 1.0
*
* @return string $rules Rules that will be printed
*/
function get_rocket_htaccess_etag() { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals
$rules = '# FileETag None is not enough for every server.' . PHP_EOL;
$rules .= '<IfModule mod_headers.c>' . PHP_EOL;
$rules .= 'Header unset ETag' . PHP_EOL;
$rules .= '</IfModule>' . PHP_EOL . PHP_EOL;
$rules .= '# Since were sending far-future expires, we dont need ETags for static content.' . PHP_EOL;
$rules .= '# developer.yahoo.com/performance/rules.html#etags' . PHP_EOL;
$rules .= 'FileETag None' . PHP_EOL . PHP_EOL;
/**
* Filter rules to remove the etag
*
* @since 1.0
*
* @param string $rules Rules that will be printed.
*/
$rules = apply_filters( 'rocket_htaccess_etag', $rules );
return $rules;
}
/**
* Rules to Cross-origin fonts sharing when CDN is used
*
* @since 2.4
*
* @return string $rules Rules that will be printed
*/
function get_rocket_htaccess_web_fonts_access() { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals
if ( ! get_rocket_option( 'cdn', false ) ) {
return;
}
$rules = '# Send CORS headers if browsers request them; enabled by default for images.' . PHP_EOL;
$rules .= '<IfModule mod_setenvif.c>' . PHP_EOL;
$rules .= '<IfModule mod_headers.c>' . PHP_EOL;
$rules .= '# mod_headers, y u no match by Content-Type?!' . PHP_EOL;
$rules .= '<FilesMatch "\.(cur|gif|png|jpe?g|svgz?|ico|webp)$">' . PHP_EOL;
$rules .= 'SetEnvIf Origin ":" IS_CORS' . PHP_EOL;
$rules .= 'Header set Access-Control-Allow-Origin "*" env=IS_CORS' . PHP_EOL;
$rules .= '</FilesMatch>' . PHP_EOL;
$rules .= '</IfModule>' . PHP_EOL;
$rules .= '</IfModule>' . PHP_EOL . PHP_EOL;
$rules .= '# Allow access to web fonts from all domains.' . PHP_EOL;
$rules .= '<FilesMatch "\.(eot|otf|tt[cf]|woff2?)$">' . PHP_EOL;
$rules .= '<IfModule mod_headers.c>' . PHP_EOL;
$rules .= 'Header set Access-Control-Allow-Origin "*"' . PHP_EOL;
$rules .= '</IfModule>' . PHP_EOL;
$rules .= '</FilesMatch>' . PHP_EOL . PHP_EOL;
// @codingStandardsIgnoreEnd
/**
* Filter rules to Cross-origin fonts sharing
*
* @since 1.0
*
* @param string $rules Rules that will be printed.
*/
$rules = apply_filters( 'rocket_htaccess_web_fonts_access', $rules );
return $rules;
}
/**
* Tell if WP rewrite rules are present in a given string.
*
* @since 3.2.4
* @author Grégory Viguier
*
* @param string $content Htaccess content.
* @return bool
*/
function rocket_has_wp_htaccess_rules( $content ) {
if ( is_multisite() ) {
$has_wp_rules = strpos( $content, '# add a trailing slash to /wp-admin' ) !== false;
} else {
$has_wp_rules = strpos( $content, '# BEGIN WordPress' ) !== false;
}
/**
* Tell if WP rewrite rules are present in a given string.
*
* @since 3.2.4
* @author Grégory Viguier
*
* @param bool $has_wp_rules True when present. False otherwise.
* @param string $content .htaccess content.
*/
return apply_filters( 'rocket_has_wp_htaccess_rules', $has_wp_rules, $content );
}
/**
* Check if WP Rocket htaccess rules are already present in the file
*
* @since 3.3.5
* @author Remy Perona
*
* @return bool
*/
function rocket_check_htaccess_rules() {
if ( ! function_exists( 'get_home_path' ) ) {
require_once ABSPATH . 'wp-admin/includes/file.php';
}
$htaccess_file = get_home_path() . '.htaccess';
if ( ! rocket_direct_filesystem()->is_readable( $htaccess_file ) ) {
return false;
}
$htaccess = rocket_direct_filesystem()->get_contents( $htaccess_file );
if ( preg_match( '/\s*# BEGIN WP Rocket.*# END WP Rocket\s*?/isU', $htaccess ) ) {
return true;
}
return false;
}

View File

@@ -0,0 +1,563 @@
<?php
defined( 'ABSPATH' ) || exit;
/**
* Get all langs to display in admin bar for WPML
*
* @since 1.3.0
*
* @return array $langlinks List of active languages
*/
function get_rocket_wpml_langs_for_admin_bar() { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals
global $sitepress;
$langlinks = [];
foreach ( $sitepress->get_active_languages() as $lang ) {
// Get flag.
$flag = $sitepress->get_flag( $lang['code'] );
if ( $flag->from_template ) {
$wp_upload_dir = wp_upload_dir();
$flag_url = $wp_upload_dir['baseurl'] . '/flags/' . $flag->flag;
} else {
$flag_url = ICL_PLUGIN_URL . '/res/flags/' . $flag->flag;
}
$langlinks[] = [
'code' => $lang['code'],
'current' => $lang['code'] === $sitepress->get_current_language(),
'anchor' => $lang['display_name'],
'flag' => '<img class="icl_als_iclflag" src="' . esc_url( $flag_url ) . '" alt="' . esc_attr( $lang['code'] ) . '" width="18" height="12" />',
];
}
if ( isset( $_GET['lang'] ) && 'all' === $_GET['lang'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
array_unshift(
$langlinks,
[
'code' => 'all',
'current' => 'all' === $sitepress->get_current_language(),
'anchor' => __( 'All languages', 'rocket' ),
'flag' => '<img class="icl_als_iclflag" src="' . ICL_PLUGIN_URL . '/res/img/icon16.png" alt="all" width="16" height="16" />',
]
);
} else {
array_push(
$langlinks,
[
'code' => 'all',
'current' => 'all' === $sitepress->get_current_language(),
'anchor' => __( 'All languages', 'rocket' ),
'flag' => '<img class="icl_als_iclflag" src="' . ICL_PLUGIN_URL . '/res/img/icon16.png" alt="all" width="16" height="16" />',
]
);
}
return $langlinks;
}
/**
* Get all langs to display in admin bar for qTranslate
*
* @since 2.7 add fork param
* @since 1.3.5
*
* @param string $fork qTranslate fork name.
* @return array $langlinks List of active languages
*/
function get_rocket_qtranslate_langs_for_admin_bar( $fork = '' ) { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals
global $q_config;
$langlinks = [];
$currentlang = [];
foreach ( $q_config['enabled_languages'] as $lang ) {
$langlinks[ $lang ] = [
'code' => $lang,
'anchor' => $q_config['language_name'][ $lang ],
'flag' => '<img src="' . esc_url( trailingslashit( WP_CONTENT_URL ) . $q_config['flag_location'] . $q_config['flag'][ $lang ] ) . '" alt="' . esc_attr( $q_config['language_name'][ $lang ] ) . '" width="18" height="12" />',
];
}
if ( isset( $_GET['lang'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
$lang = sanitize_key( $_GET['lang'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
if ( 'x' === $fork ) {
if ( qtranxf_isEnabled( $lang ) ) {
$currentlang[ $lang ] = $langlinks[ $lang ];
unset( $langlinks[ $lang ] );
$langlinks = $currentlang + $langlinks;
}
} elseif ( qtrans_isEnabled( $lang ) ) {
$currentlang[ $lang ] = $langlinks[ $lang ];
unset( $langlinks[ $lang ] );
$langlinks = $currentlang + $langlinks;
}
}
return $langlinks;
}
/**
* Get all langs to display in admin bar for Polylang
*
* @since 2.2
*
* @return array $langlinks List of active languages
*/
function get_rocket_polylang_langs_for_admin_bar() { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals
global $polylang;
$langlinks = [];
$currentlang = [];
$langs = [];
$img = '';
$pll = function_exists( 'PLL' ) ? PLL() : $polylang;
if ( isset( $pll ) ) {
$langs = $pll->model->get_languages_list();
if ( ! empty( $langs ) ) {
foreach ( $langs as $lang ) {
if ( ! empty( $lang->flag ) ) {
$img = strpos( $lang->flag, 'img' ) !== false ? $lang->flag . '&nbsp;' : $lang->flag;
}
if ( isset( $pll->curlang->slug ) && $lang->slug === $pll->curlang->slug ) {
$currentlang[ $lang->slug ] = [
'code' => $lang->slug,
'anchor' => $lang->name,
'flag' => $img,
];
} else {
$langlinks[ $lang->slug ] = [
'code' => $lang->slug,
'anchor' => $lang->name,
'flag' => $img,
];
}
}
}
}
return $currentlang + $langlinks;
}
/**
* Tell if a translation plugin is activated.
*
* @since 2.0
* @since 3.2.1 Return an identifier on success instead of true.
*
* @return string|bool An identifier corresponding to the active plugin. False otherwize.
*/
function rocket_has_i18n() {
global $sitepress, $q_config, $polylang;
if ( ! empty( $sitepress ) && is_object( $sitepress ) && method_exists( $sitepress, 'get_active_languages' ) ) {
// WPML.
return 'wpml';
}
if ( ! empty( $polylang ) && function_exists( 'pll_languages_list' ) ) {
$languages = pll_languages_list();
if ( empty( $languages ) ) {
return false;
}
// Polylang, Polylang Pro.
return 'polylang';
}
if ( ! empty( $q_config ) && is_array( $q_config ) ) {
if ( function_exists( 'qtranxf_convertURL' ) ) {
// qTranslate-x.
return 'qtranslate-x';
}
if ( function_exists( 'qtrans_convertURL' ) ) {
// qTranslate.
return 'qtranslate';
}
}
return false;
}
/**
* Get infos of all active languages.
*
* @since 2.0
*
* @return array A list of language codes.
*/
function get_rocket_i18n_code() { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals
$i18n_plugin = rocket_has_i18n();
if ( ! $i18n_plugin ) {
return false;
}
if ( 'wpml' === $i18n_plugin ) {
// WPML.
return array_keys( $GLOBALS['sitepress']->get_active_languages() );
}
if ( 'qtranslate' === $i18n_plugin || 'qtranslate-x' === $i18n_plugin ) {
// qTranslate, qTranslate-x.
return ! empty( $GLOBALS['q_config']['enabled_languages'] ) ? $GLOBALS['q_config']['enabled_languages'] : [];
}
if ( 'polylang' === $i18n_plugin ) {
// Polylang, Polylang Pro.
return pll_languages_list();
}
return false;
}
/**
* Get all active languages host
*
* @since 2.6.8
*
* @return array $urls List of all active languages host
*/
function get_rocket_i18n_host() { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals
$langs_host = [];
$langs = get_rocket_i18n_uri();
if ( $langs ) {
foreach ( $langs as $lang ) {
$langs_host[] = rocket_extract_url_component( $lang, PHP_URL_HOST );
}
}
return $langs_host;
}
/**
* Get all active languages URI.
*
* @since 2.0
*
* @return array $urls List of all active languages URI.
*/
function get_rocket_i18n_uri() { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals
$i18n_plugin = rocket_has_i18n();
$urls = [];
if ( 'wpml' === $i18n_plugin ) {
// WPML.
foreach ( get_rocket_i18n_code() as $lang ) {
$urls[] = $GLOBALS['sitepress']->language_url( $lang );
}
} elseif ( 'qtranslate' === $i18n_plugin || 'qtranslate-x' === $i18n_plugin ) {
// qTranslate, qTranslate-x.
foreach ( get_rocket_i18n_code() as $lang ) {
if ( 'qtranslate' === $i18n_plugin ) {
$urls[] = qtrans_convertURL( home_url(), $lang, true );
} else {
$urls[] = qtranxf_convertURL( home_url(), $lang, true );
}
}
} elseif ( 'polylang' === $i18n_plugin ) {
// Polylang, Polylang Pro.
$pll = function_exists( 'PLL' ) ? PLL() : $GLOBALS['polylang'];
if ( ! empty( $pll ) && is_object( $pll ) ) {
$urls = wp_list_pluck( $pll->model->get_languages_list(), 'search_url' );
}
}
if ( empty( $urls ) ) {
$urls[] = home_url();
}
return $urls;
}
/**
* Get directories paths to preserve languages when purging a domain.
* This function is required when the domains of languages (other than the default) are managed by subdirectories.
* By default, when you clear the cache of the french website with the domain example.com, all subdirectory like /en/
* and /de/ are deleted. But, if you have a domain for your english and german websites with example.com/en/ and
* example.com/de/, you want to keep the /en/ and /de/ directory when the french domain is cleared.
*
* @since 3.5.5 Normalize paths + micro-optimization by passing in the cache path.
* @since 2.0
*
* @param string $current_lang The current language code.
* @param string $cache_path Optional. WP Rocket's cache path.
*
* @return array A list of directories path to preserve.
*/
function get_rocket_i18n_to_preserve( $current_lang, $cache_path = '' ) { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals
// Must not be an empty string.
if ( empty( $current_lang ) ) {
return [];
}
// Must not be anything else but a string.
if ( ! is_string( $current_lang ) ) {
return [];
}
$i18n_plugin = rocket_has_i18n();
if ( ! $i18n_plugin ) {
return [];
}
$langs = get_rocket_i18n_code();
if ( empty( $langs ) ) {
return [];
}
// Remove current lang to the preserve dirs.
$langs = array_diff( $langs, [ $current_lang ] );
if ( '' === $cache_path ) {
$cache_path = _rocket_get_wp_rocket_cache_path();
}
// Stock all URLs of langs to preserve.
$langs_to_preserve = [];
foreach ( $langs as $lang ) {
$parse_url = get_rocket_parse_url( get_rocket_i18n_home_url( $lang ) );
$langs_to_preserve[] = _rocket_normalize_path(
"{$cache_path}{$parse_url['host']}(.*)/" . trim( $parse_url['path'], '/' ),
true // escape directory separators for regex.
);
}
/**
* Filter directories path to preserve of cache purge.
*
* @since 2.1
*
* @param array $langs_to_preserve List of directories path to preserve.
*/
return (array) apply_filters( 'rocket_langs_to_preserve', $langs_to_preserve );
}
/**
* Get all languages subdomains URLs
*
* @since 2.1
*
* @return array $urls List of languages subdomains URLs
*/
function get_rocket_i18n_subdomains() { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals
$i18n_plugin = rocket_has_i18n();
if ( ! $i18n_plugin ) {
return [];
}
switch ( $i18n_plugin ) {
// WPML.
case 'wpml':
$option = get_option( 'icl_sitepress_settings' );
if ( 2 === (int) $option['language_negotiation_type'] ) {
return get_rocket_i18n_uri();
}
break;
// qTranslate.
case 'qtranslate':
if ( 3 === (int) $GLOBALS['q_config']['url_mode'] ) {
return get_rocket_i18n_uri();
}
break;
// qTranslate-x.
case 'qtranslate-x':
if ( 3 === (int) $GLOBALS['q_config']['url_mode'] || 4 === (int) $GLOBALS['q_config']['url_mode'] ) {
return get_rocket_i18n_uri();
}
break;
// Polylang, Polylang Pro.
case 'polylang':
$pll = function_exists( 'PLL' ) ? PLL() : $GLOBALS['polylang'];
if ( ! empty( $pll ) && is_object( $pll ) && ( 2 === (int) $pll->options['force_lang'] || 3 === (int) $pll->options['force_lang'] ) ) {
return get_rocket_i18n_uri();
}
}
return [];
}
/**
* Get home URL of a specific lang.
*
* @since 2.2
*
* @param string $lang The language code. Default is an empty string.
* @return string $url
*/
function get_rocket_i18n_home_url( $lang = '' ) { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals
$i18n_plugin = rocket_has_i18n();
if ( ! $i18n_plugin ) {
return home_url();
}
switch ( $i18n_plugin ) {
// WPML.
case 'wpml':
return $GLOBALS['sitepress']->language_url( $lang );
// qTranslate.
case 'qtranslate':
return qtrans_convertURL( home_url(), $lang, true );
// qTranslate-x.
case 'qtranslate-x':
return qtranxf_convertURL( home_url(), $lang, true );
// Polylang, Polylang Pro.
case 'polylang':
$pll = function_exists( 'PLL' ) ? PLL() : $GLOBALS['polylang'];
if ( ! empty( $pll->options['force_lang'] ) && isset( $pll->links ) ) {
return pll_home_url( $lang );
}
}
return home_url();
}
/**
* Get all translated path of a specific post with ID.
*
* @since 2.4
*
* @param int $post_id Post ID.
* @param string $post_type Post Type.
* @param string $regex Regex to include at the end.
* @return array
*/
function get_rocket_i18n_translated_post_urls( $post_id, $post_type = 'page', $regex = null ) { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals
$path = wp_parse_url( get_permalink( $post_id ), PHP_URL_PATH );
if ( empty( $path ) ) {
return [];
}
$i18n_plugin = rocket_has_i18n();
$urls = [];
switch ( $i18n_plugin ) {
// WPML.
case 'wpml':
$langs = get_rocket_i18n_code();
if ( $langs ) {
foreach ( $langs as $lang ) {
$urls[] = wp_parse_url( get_permalink( icl_object_id( $post_id, $post_type, true, $lang ) ), PHP_URL_PATH ) . $regex;
}
}
break;
// qTranslate & qTranslate-x.
case 'qtranslate':
case 'qtranslate-x':
$langs = $GLOBALS['q_config']['enabled_languages'];
$langs = array_diff( $langs, [ $GLOBALS['q_config']['default_language'] ] );
$urls[] = wp_parse_url( get_permalink( $post_id ), PHP_URL_PATH ) . $regex;
if ( $langs ) {
$url = get_permalink( $post_id );
foreach ( $langs as $lang ) {
if ( 'qtranslate' === $i18n_plugin ) {
$urls[] = wp_parse_url( qtrans_convertURL( $url, $lang, true ), PHP_URL_PATH ) . $regex;
} elseif ( 'qtranslate-x' === $i18n_plugin ) {
$urls[] = wp_parse_url( qtranxf_convertURL( $url, $lang, true ), PHP_URL_PATH ) . $regex;
}
}
}
break;
// Polylang.
case 'polylang':
if ( function_exists( 'PLL' ) && is_object( PLL()->model ) ) {
$translations = pll_get_post_translations( $post_id );
} elseif ( ! empty( $GLOBALS['polylang']->model ) && is_object( $GLOBALS['polylang']->model ) ) {
$translations = $GLOBALS['polylang']->model->get_translations( 'page', $post_id );
}
if ( ! empty( $translations ) ) {
foreach ( $translations as $post_id ) {
$urls[] = wp_parse_url( get_permalink( $post_id ), PHP_URL_PATH ) . $regex;
}
}
}
if ( trim( $path, '/' ) !== '' ) {
$urls[] = $path . $regex;
}
$urls = array_unique( $urls );
return $urls;
}
/**
* Returns the home URL, without WPML filters if the plugin is active
*
* @since 3.2.4
* @author Remy Perona
*
* @param string $path Path to add to the home URL.
* @return string
*/
function rocket_get_home_url( $path = '' ) {
global $wpml_url_filters;
static $home_url = [];
static $has_wpml;
if ( isset( $home_url[ $path ] ) ) {
return $home_url[ $path ];
}
if ( ! isset( $has_wpml ) ) {
$has_wpml = $wpml_url_filters && is_object( $wpml_url_filters ) && method_exists( $wpml_url_filters, 'home_url_filter' );
}
if ( $has_wpml ) {
remove_filter( 'home_url', [ $wpml_url_filters, 'home_url_filter' ], -10 );
}
$home_url[ $path ] = home_url( $path );
if ( $has_wpml ) {
add_filter( 'home_url', [ $wpml_url_filters, 'home_url_filter' ], -10, 4 );
}
return $home_url[ $path ];
}
/**
* Gets the current language if Polylang or WPML is used
*
* @since 3.3.3
* @author Remy Perona
*
* @return string|bool
*/
function rocket_get_current_language() {
$i18n_plugin = rocket_has_i18n();
if ( ! $i18n_plugin ) {
return false;
}
if ( 'polylang' === $i18n_plugin && function_exists( 'pll_current_language' ) ) {
return pll_current_language();
} elseif ( 'wpml' === $i18n_plugin ) {
return apply_filters( 'wpml_current_language', null ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals
}
return false;
}

View File

@@ -0,0 +1,749 @@
<?php
use WP_Rocket\Admin\Options;
use WP_Rocket\Admin\Options_Data;
use WP_Rocket\Logger\Logger;
defined( 'ABSPATH' ) || exit;
/**
* A wrapper to easily get rocket option
*
* @since 3.0 Use the new options classes
* @since 1.3.0
*
* @param string $option The option name.
* @param bool $default (default: false) The default value of option.
* @return mixed The option value
*/
function get_rocket_option( $option, $default = false ) { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals
$options_api = new Options( 'wp_rocket_' );
$options = new Options_Data( $options_api->get( 'settings', [] ) );
return $options->get( $option, $default );
}
/**
* Update a WP Rocket option.
*
* @since 3.0 Use the new options classes
* @since 2.7
*
* @param string $key The option name.
* @param string $value The value of the option.
* @return void
*/
function update_rocket_option( $key, $value ) { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals
$options_api = new Options( 'wp_rocket_' );
$options = new Options_Data( $options_api->get( 'settings', [] ) );
$options->set( $key, $value );
$options_api->set( 'settings', $options->get_options() );
}
/**
* Check whether the plugin is active by checking the active_plugins list.
*
* @since 1.3.0
*
* @source wp-admin/includes/plugin.php
*
* @param string $plugin Plugin folder/main file.
*
* @return boolean true when plugin is active; else false.
*/
function rocket_is_plugin_active( $plugin ) {
return (
in_array( $plugin, (array) get_option( 'active_plugins', [] ), true )
||
rocket_is_plugin_active_for_network( $plugin )
);
}
/**
* Check whether the plugin is active for the entire network.
*
* @since 1.3.0
*
* @source wp-admin/includes/plugin.php
*
* @param string $plugin Plugin folder/main file.
*
* @return bool true if multisite and plugin is active for network; else, false.
*/
function rocket_is_plugin_active_for_network( $plugin ) {
if ( ! is_multisite() ) {
return false;
}
$plugins = get_site_option( 'active_sitewide_plugins' );
return isset( $plugins[ $plugin ] );
}
/**
* Is we need to exclude some specifics options on a post.
*
* @since 2.5
*
* @param string $option The option name (lazyload, css, js, cdn).
* @return bool True if the option is deactivated
*/
function is_rocket_post_excluded_option( $option ) { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals
global $post;
if ( ! is_object( $post ) ) {
return false;
}
if ( is_home() ) {
$post_id = get_queried_object_id();
}
if ( is_singular() && isset( $post ) ) {
$post_id = $post->ID;
}
return ( isset( $post_id ) ) ? get_post_meta( $post_id, '_rocket_exclude_' . $option, true ) : false;
}
/**
* Check if we need to cache the mobile version of the website (if available)
*
* @since 1.0
*
* @return bool True if option is activated
*/
function is_rocket_cache_mobile() { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals
return get_rocket_option( 'cache_mobile', false );
}
/**
* Check if we need to generate a different caching file for mobile (if available)
*
* @since 2.7
*
* @return bool True if option is activated and if mobile caching is enabled
*/
function is_rocket_generate_caching_mobile_files() { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals
return get_rocket_option( 'cache_mobile', false ) && get_rocket_option( 'do_caching_mobile_files', false );
}
/**
* Get the domain names to DNS prefetch from WP Rocket options
*
* @since 2.8.9
* @author Remy Perona
*
* return Array An array of domain names to DNS prefetch
*/
function rocket_get_dns_prefetch_domains() {
$domains = (array) get_rocket_option( 'dns_prefetch' );
/**
* Filter list of domains to prefetch DNS
*
* @since 1.1.0
*
* @param array $domains List of domains to prefetch DNS
*/
return apply_filters( 'rocket_dns_prefetch', $domains );
}
/**
* Gets the parameters ignored during caching
*
* These parameters are ignored when checking the query string during caching to allow serving the default cache when they are present
*
* @since 3.4
* @author Remy Perona
*
* @return array
*/
function rocket_get_ignored_parameters() {
$params = [
'utm_source' => 1,
'utm_medium' => 1,
'utm_campaign' => 1,
'utm_expid' => 1,
'utm_term' => 1,
'utm_content' => 1,
'mtm_source' => 1,
'mtm_medium' => 1,
'mtm_campaign' => 1,
'mtm_keyword' => 1,
'mtm_cid' => 1,
'mtm_content' => 1,
'pk_source' => 1,
'pk_medium' => 1,
'pk_campaign' => 1,
'pk_keyword' => 1,
'pk_cid' => 1,
'pk_content' => 1,
'fb_action_ids' => 1,
'fb_action_types' => 1,
'fb_source' => 1,
'fbclid' => 1,
'campaignid' => 1,
'adgroupid' => 1,
'adid' => 1,
'gclid' => 1,
'age-verified' => 1,
'ao_noptimize' => 1,
'usqp' => 1,
'cn-reloaded' => 1,
'_ga' => 1,
'sscid' => 1,
];
/**
* Filters the ignored parameters
*
* @since 3.4
* @author Remy Perona
*
* @param array $params An array of ignored parameters as array keys.
*/
return apply_filters( 'rocket_cache_ignored_parameters', $params );
}
/**
* Get all uri we don't cache.
*
* @since 3.3.2 Exclude embedded URLs
* @since 2.6 Using json_get_url_prefix() to auto-exclude the WordPress REST API.
* @since 2.4.1 Auto-exclude WordPress REST API.
* @since 2.0
*
* @param bool $force Force the static uris to be reverted to null.
*
* @return string A pipe separated list of rejected uri.
*/
function get_rocket_cache_reject_uri( $force = false ) { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals
static $uris;
global $wp_rewrite;
if ( $force ) {
$uris = null;
}
if ( $uris ) {
return $uris;
}
$uris = (array) get_rocket_option( 'cache_reject_uri', [] );
$home_root = rocket_get_home_dirname();
$home_root_escaped = preg_quote( $home_root, '/' ); // The site is not at the domain root, it's in a folder.
$home_root_len = strlen( $home_root );
if ( '' !== $home_root && $uris ) {
foreach ( $uris as $i => $uri ) {
/**
* Since these URIs can be regex patterns like `/homeroot(/.+)/`, we can't simply search for the string `/homeroot/` (nor `/homeroot`).
* So this pattern searchs for `/homeroot/` and `/homeroot(/`.
*/
if ( ! preg_match( '/' . $home_root_escaped . '\(?\//', $uri ) ) {
// Reject URIs located outside site's folder.
unset( $uris[ $i ] );
continue;
}
// Remove the home directory.
$uris[ $i ] = substr( $uri, $home_root_len );
}
}
// Exclude feeds.
$uris[] = '/(.+/)?' . $wp_rewrite->feed_base . '/?.+/?';
// Exlude embedded URLs.
$uris[] = '/(?:.+/)?embed/';
/**
* Filter the rejected uri
*
* @since 2.1
*
* @param array $uris List of rejected uri
*/
$uris = apply_filters( 'rocket_cache_reject_uri', $uris );
$uris = array_filter( $uris );
if ( ! $uris ) {
return '';
}
if ( '' !== $home_root ) {
foreach ( $uris as $i => $uri ) {
if ( preg_match( '/' . $home_root_escaped . '\(?\//', $uri ) ) {
// Remove the home directory from the new URIs.
$uris[ $i ] = substr( $uri, $home_root_len );
}
}
}
$uris = implode( '|', $uris );
if ( '' !== $home_root ) {
// Add the home directory back.
$uris = $home_root . '(' . $uris . ')';
}
return $uris;
}
/**
* Get all cookie names we don't cache.
*
* @since 2.0
*
* @return string A pipe separated list of rejected cookies.
*/
function get_rocket_cache_reject_cookies() { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals
$logged_in_cookie = explode( COOKIEHASH, LOGGED_IN_COOKIE );
$logged_in_cookie = array_map( 'preg_quote', $logged_in_cookie );
$logged_in_cookie = implode( '.+', $logged_in_cookie );
$cookies = get_rocket_option( 'cache_reject_cookies', [] );
$cookies[] = $logged_in_cookie;
$cookies[] = 'wp-postpass_';
$cookies[] = 'wptouch_switch_toggle';
$cookies[] = 'comment_author_';
$cookies[] = 'comment_author_email_';
/**
* Filter the rejected cookies.
*
* @since 2.1
*
* @param array $cookies List of rejected cookies.
*/
$cookies = (array) apply_filters( 'rocket_cache_reject_cookies', $cookies );
$cookies = array_filter( $cookies );
$cookies = array_flip( array_flip( $cookies ) );
return implode( '|', $cookies );
}
/**
* Get list of mandatory cookies to be able to cache pages.
*
* @since 2.7
*
* @return string A pipe separated list of mandatory cookies.
*/
function get_rocket_cache_mandatory_cookies() { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals
$cookies = [];
/**
* Filter list of mandatory cookies.
*
* @since 2.7
*
* @param array $cookies List of mandatory cookies.
*/
$cookies = (array) apply_filters( 'rocket_cache_mandatory_cookies', $cookies );
$cookies = array_filter( $cookies );
$cookies = array_flip( array_flip( $cookies ) );
return implode( '|', $cookies );
}
/**
* Get list of dynamic cookies.
*
* @since 2.7
*
* @return array List of dynamic cookies.
*/
function get_rocket_cache_dynamic_cookies() { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals
$cookies = [];
/**
* Filter list of dynamic cookies.
*
* @since 2.7
*
* @param array $cookies List of dynamic cookies.
*/
$cookies = (array) apply_filters( 'rocket_cache_dynamic_cookies', $cookies );
$cookies = array_filter( $cookies );
$cookies = array_unique( $cookies );
return $cookies;
}
/**
* Get all User-Agent we don't allow to get cache files.
*
* @since 2.3.5
*
* @return string A pipe separated list of rejected User-Agent.
*/
function get_rocket_cache_reject_ua() { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals
$ua = get_rocket_option( 'cache_reject_ua', [] );
$ua[] = 'facebookexternalhit';
/**
* Filter the rejected User-Agent
*
* @since 2.3.5
*
* @param array $ua List of rejected User-Agent.
*/
$ua = (array) apply_filters( 'rocket_cache_reject_ua', $ua );
$ua = array_filter( $ua );
$ua = array_flip( array_flip( $ua ) );
$ua = implode( '|', $ua );
return str_replace( [ ' ', '\\\\ ' ], '\\ ', $ua );
}
/**
* Get all query strings which can be cached.
*
* @since 2.3
*
* @return array List of query strings which can be cached.
*/
function get_rocket_cache_query_string() { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals
$query_strings = get_rocket_option( 'cache_query_strings', [] );
/**
* Filter query strings which can be cached.
*
* @since 2.3
*
* @param array $query_strings List of query strings which can be cached.
*/
$query_strings = (array) apply_filters( 'rocket_cache_query_strings', $query_strings );
$query_strings = array_filter( $query_strings );
$query_strings = array_flip( array_flip( $query_strings ) );
return $query_strings;
}
/**
* Get list of JS files to be excluded from defer JS.
*
* @since 2.10
* @author Remy Perona
*
* @return array An array of URLs for the JS files to be excluded.
*/
function get_rocket_exclude_defer_js() { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals
$exclude_defer_js = [
'gist.github.com',
'content.jwplatform.com',
'js.hsforms.net',
'www.uplaunch.com',
'google.com/recaptcha',
'widget.reviews.co.uk',
'verify.authorize.net/anetseal',
'lib/admin/assets/lib/webfont/webfont.min.js',
'app.mailerlite.com',
'widget.reviews.io',
'simplybook.(.*)/v2/widget/widget.js',
'/wp-includes/js/dist/i18n.min.js',
'/wp-content/plugins/wpfront-notification-bar/js/wpfront-notification-bar(.*).js',
'/wp-content/plugins/oxygen/component-framework/vendor/aos/aos.js',
'static.mailerlite.com/data/(.*).js',
'cdn.voxpow.com/static/libs/v1/(.*).js',
'cdn.voxpow.com/media/trackers/js/(.*).js',
];
if ( get_rocket_option( 'defer_all_js', 0 ) && get_rocket_option( 'defer_all_js_safe', 0 ) ) {
$jquery = site_url( wp_scripts()->registered['jquery-core']->src );
$jetpack_jquery = 'c0.wp.com/c/(?:.+)/wp-includes/js/jquery/jquery.js';
$googleapis_jquery = 'ajax.googleapis.com/ajax/libs/jquery/(?:.+)/jquery(?:\.min)?.js';
$cdnjs_jquery = 'cdnjs.cloudflare.com/ajax/libs/jquery/(?:.+)/jquery(?:\.min)?.js';
$code_jquery = 'code.jquery.com/jquery-.*(?:\.min|slim)?.js';
$exclude_defer_js[] = rocket_clean_exclude_file( $jquery );
$exclude_defer_js[] = $jetpack_jquery;
$exclude_defer_js[] = $googleapis_jquery;
$exclude_defer_js[] = $cdnjs_jquery;
$exclude_defer_js[] = $code_jquery;
}
/**
* Filter list of Deferred JavaScript files
*
* @since 2.10
* @author Remy Perona
*
* @param array $exclude_defer_js An array of URLs for the JS files to be excluded.
*/
$exclude_defer_js = apply_filters( 'rocket_exclude_defer_js', $exclude_defer_js );
foreach ( $exclude_defer_js as $i => $exclude ) {
$exclude_defer_js[ $i ] = str_replace( '#', '\#', $exclude );
}
return $exclude_defer_js;
}
/**
* Determine if the key is valid
*
* @since 2.9 use hash_equals() to compare the hash values
* @since 1.0
*
* @return bool true if everything is ok, false otherwise
*/
function rocket_valid_key() {
$rocket_secret_key = get_rocket_option( 'secret_key' );
if ( ! $rocket_secret_key ) {
return false;
}
return 8 === strlen( get_rocket_option( 'consumer_key' ) ) && hash_equals( $rocket_secret_key, hash( 'crc32', get_rocket_option( 'consumer_email' ) ) );
}
/**
* Determine if the key is valid.
*
* @since 2.9.7 Remove arguments ($type & $data).
* @since 2.9.7 Stop to auto-check the validation each 1 & 30 days.
* @since 2.2 The function do the live check and update the option.
*
* @return bool|array
*/
function rocket_check_key() {
// Recheck the license.
$return = rocket_valid_key();
if ( $return ) {
rocket_delete_licence_data_file();
return $return;
}
Logger::info( 'LICENSE VALIDATION PROCESS STARTED.', [ 'license validation process' ] );
$response = wp_remote_get(
rocket_get_constant( 'WP_ROCKET_WEB_VALID' ),
[
'timeout' => 30,
]
);
if ( is_wp_error( $response ) ) {
Logger::error(
'License validation failed.',
[
'license validation process',
'request_error' => $response->get_error_messages(),
]
);
set_transient( 'rocket_check_key_errors', $response->get_error_messages() );
return $return;
}
$body = wp_remote_retrieve_body( $response );
$json = json_decode( $body );
if ( null === $json ) {
if ( '' === $body ) {
Logger::error( 'License validation failed. No body available in response.', [ 'license validation process' ] );
// Translators: %1$s = opening em tag, %2$s = closing em tag, %3$s = opening link tag, %4$s closing link tag.
$message = __( 'License validation failed. Our server could not resolve the request from your website.', 'rocket' ) . '<br>' . sprintf( __( 'Try clicking %1$sSave Changes%2$s below. If the error persists, follow %3$sthis guide%4$s.', 'rocket' ), '<em>', '</em>', '<a href="https://docs.wp-rocket.me/article/100-resolving-problems-with-license-validation#general">', '</a>' );
set_transient( 'rocket_check_key_errors', [ $message ] );
return $return;
}
Logger::error(
'License validation failed.',
[
'license validation process',
'response_body' => $body,
]
);
if ( 'NULLED' === $body ) {
// Translators: %1$s = opening link tag, %2$s = closing link tag.
$message = __( 'License validation failed. You may be using a nulled version of the plugin. Please do the following:', 'rocket' ) . '<ul><li>' . sprintf( __( 'Login to your WP Rocket %1$saccount%2$s', 'rocket' ), '<a href="https://wp-rocket.me/account/" rel="noopener noreferrer" target=_"blank">', '</a>' ) . '</li><li>' . __( 'Download the zip file', 'rocket' ) . '<li></li>' . __( 'Reinstall', 'rocket' ) . '</li></ul>' . sprintf( __( 'If you do not have a WP Rocket account, please %1$spurchase a license%2$s.', 'rocket' ), '<a href="https://wp-rocket.me/" rel="noopener noreferrer" target="_blank">', '</a>' );
set_transient( 'rocket_check_key_errors', [ $message ] );
return $return;
}
if ( 'BAD_USER' === $body ) {
// Translators: %1$s = opening link tag, %2$s = closing link tag.
$message = __( 'License validation failed. This user account does not exist in our database.', 'rocket' ) . '<br>' . sprintf( __( 'To resolve, please contact support.', 'rocket' ), '<a href="https://wp-rocket.me/support/" rel="noopener noreferrer" target=_"blank">', '</a>' );
set_transient( 'rocket_check_key_errors', [ $message ] );
return $return;
}
if ( 'USER_BLOCKED' === $body ) {
// Translators: %1$s = opening link tag, %2$s = closing link tag.
$message = __( 'License validation failed. This user account is blocked.', 'rocket' ) . '<br>' . sprintf( __( 'Please see %1$sthis guide%2$s for more info.', 'rocket' ), '<a href="https://docs.wp-rocket.me/article/100-resolving-problems-with-license-validation#errors" rel="noopener noreferrer" target=_"blank">', '</a>' );
set_transient( 'rocket_check_key_errors', [ $message ] );
return $return;
}
// Translators: %1$s = opening em tag, %2$s = closing em tag, %3$s = opening link tag, %4$s closing link tag.
$message = __( 'License validation failed. Our server could not resolve the request from your website.', 'rocket' ) . '<br>' . sprintf( __( 'Try clicking %1$sSave Changes%2$s below. If the error persists, follow %3$sthis guide%4$s.', 'rocket' ), '<em>', '</em>', '<a href="https://docs.wp-rocket.me/article/100-resolving-problems-with-license-validation#general" rel="noopener noreferrer" target=_"blank">', '</a>' );
set_transient( 'rocket_check_key_errors', [ $message ] );
return $return;
}
$rocket_options = [];
$rocket_options['consumer_key'] = $json->data->consumer_key;
$rocket_options['consumer_email'] = $json->data->consumer_email;
if ( ! $json->success ) {
$messages = [
// Translators: %1$s = opening link tag, %2$s = closing link tag.
'BAD_LICENSE' => __( 'Your license is not valid.', 'rocket' ) . '<br>' . sprintf( __( 'Make sure you have an active %1$sWP Rocket license%2$s.', 'rocket' ), '<a href="https://wp-rocket.me/" rel="noopener noreferrer" target="_blank">', '</a>' ),
// Translators: %1$s = opening link tag, %2$s = closing link tag, %3$s = opening link tag.
'BAD_NUMBER' => __( 'You have added as many sites as your current license allows.', 'rocket' ) . '<br>' . sprintf( __( 'Upgrade your %1$saccount%2$s or %3$stransfer your license%2$s to this domain.', 'rocket' ), '<a href="https://wp-rocket.me/account/" rel="noopener noreferrer" target=_"blank">', '</a>', '<a href="https://docs.wp-rocket.me/article/28-transfering-your-license-to-another-site" rel="noopener noreferrer" target=_"blank">' ),
// Translators: %1$s = opening link tag, %2$s = closing link tag.
'BAD_SITE' => __( 'This website is not allowed.', 'rocket' ) . '<br>' . sprintf( __( 'Please %1$scontact support%2$s.', 'rocket' ), '<a href="https://wp-rocket.me/support/" rel="noopener noreferrer" target=_"blank">', '</a>' ),
// Translators: %1$s = opening link tag, %2$s = closing link tag.
'BAD_KEY' => __( 'This license key is not recognized.', 'rocket' ) . '<ul><li>' . sprintf( __( 'Login to your WP Rocket %1$saccount%2$s', 'rocket' ), '<a href="https://wp-rocket.me/account/" rel="noopener noreferrer" target=_"blank">', '</a>' ) . '</li><li>' . __( 'Download the zip file', 'rocket' ) . '<li></li>' . __( 'Reinstall', 'rocket' ) . '</li></ul>' . sprintf( __( 'If the issue persists, please %1$scontact support%2$s.', 'rocket' ), '<a href="https://wp-rocket.me/support/" rel="noopener noreferrer" target=_"blank">', '</a>' ),
];
$rocket_options['secret_key'] = '';
// Translators: %s = error message returned.
set_transient( 'rocket_check_key_errors', [ sprintf( __( 'License validation failed: %s', 'rocket' ), $messages[ $json->data->reason ] ) ] );
Logger::error(
'License validation failed.',
[
'license validation process',
'response_error' => $json->data->reason,
]
);
set_transient( rocket_get_constant( 'WP_ROCKET_SLUG' ), $rocket_options );
return $rocket_options;
}
$rocket_options['secret_key'] = $json->data->secret_key;
if ( ! get_rocket_option( 'license' ) ) {
$rocket_options['license'] = '1';
}
Logger::info( 'License validation successful.', [ 'license validation process' ] );
set_transient( rocket_get_constant( 'WP_ROCKET_SLUG' ), $rocket_options );
delete_transient( 'rocket_check_key_errors' );
rocket_delete_licence_data_file();
return $rocket_options;
}
/**
* Deletes the licence-data.php file if it exists
*
* @since 3.5
* @author Remy Perona
*
* @return void
*/
function rocket_delete_licence_data_file() {
if ( is_multisite() ) {
return;
}
$rocket_path = rocket_get_constant( 'WP_ROCKET_PATH' );
if ( ! rocket_direct_filesystem()->exists( $rocket_path . 'licence-data.php' ) ) {
return;
}
rocket_direct_filesystem()->delete( $rocket_path . 'licence-data.php' );
}
/**
* Is WP a MultiSite and a subfolder install?
*
* @since 3.1.1
* @author Grégory Viguier
*
* @return bool
*/
function rocket_is_subfolder_install() {
global $wpdb;
static $subfolder_install;
if ( isset( $subfolder_install ) ) {
return $subfolder_install;
}
if ( is_multisite() ) {
$subfolder_install = ! is_subdomain_install();
} elseif ( ! is_null( $wpdb->sitemeta ) ) {
$subfolder_install = ! $wpdb->get_var( "SELECT meta_value FROM $wpdb->sitemeta WHERE site_id = 1 AND meta_key = 'subdomain_install'" ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery
} else {
$subfolder_install = false;
}
return $subfolder_install;
}
/**
* Get the name of the "home directory", in case the home URL is not at the domain's root.
* It can be seen like the `RewriteBase` from the .htaccess file, but without the trailing slash.
*
* @since 3.1.1
* @author Grégory Viguier
*
* @return string
*/
function rocket_get_home_dirname() {
static $home_root;
if ( isset( $home_root ) ) {
return $home_root;
}
$home_root = wp_parse_url( rocket_get_main_home_url() );
if ( ! empty( $home_root['path'] ) ) {
$home_root = '/' . trim( $home_root['path'], '/' );
$home_root = rtrim( $home_root, '/' );
} else {
$home_root = '';
}
return $home_root;
}
/**
* Get the URL of the site's root. It corresponds to the main site's home page URL.
*
* @since 3.1.1
* @author Grégory Viguier
*
* @return string
*/
function rocket_get_main_home_url() {
static $root_url;
if ( isset( $root_url ) ) {
return $root_url;
}
if ( ! is_multisite() || is_main_site() ) {
$root_url = rocket_get_home_url( '/' );
return $root_url;
}
$current_network = get_network();
if ( $current_network ) {
$root_url = set_url_scheme( 'https://' . $current_network->domain . $current_network->path );
$root_url = trailingslashit( $root_url );
} else {
$root_url = rocket_get_home_url( '/' );
}
return $root_url;
}

View File

@@ -0,0 +1,73 @@
<?php
defined( 'ABSPATH' ) || exit;
/**
* Get the permalink post
*
* @since 1.3.1
*
* @source : get_sample_permalink() in wp-admin/includes/post.php
*
* @param int $id The post ID.
* @param string $title The post title.
* @param string $name The post name.
* @return string The permalink
*/
function get_rocket_sample_permalink( $id, $title = null, $name = null ) { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals
$post = get_post( $id );
if ( ! $post ) {
return [ '', '' ];
}
$ptype = get_post_type_object( $post->post_type );
$original_status = $post->post_status;
$original_date = $post->post_date;
$original_name = $post->post_name;
// Hack: get_permalink() would return ugly permalink for drafts, so we will fake that our post is published.
if ( in_array( $post->post_status, [ 'draft', 'pending' ], true ) ) {
$post->post_status = 'publish';
$post->post_name = sanitize_title( $post->post_name ? $post->post_name : $post->post_title, $post->ID );
}
// If the user wants to set a new name -- override the current one.
// Note: if empty name is supplied -- use the title instead, see #6072.
if ( ! is_null( $name ) ) {
$post->post_name = sanitize_title( $name ? $name : $title, $post->ID );
}
$post->post_name = wp_unique_post_slug( $post->post_name, $post->ID, $post->post_status, $post->post_type, $post->post_parent );
$post->filter = 'sample';
$permalink = get_permalink( $post, false );
// Replace custom post_type Token with generic pagename token for ease of use.
$permalink = str_replace( "%$post->post_type%", '%pagename%', $permalink );
// Handle page hierarchy.
if ( $ptype->hierarchical ) {
$uri = get_page_uri( $post );
$uri = untrailingslashit( $uri );
$uri = strrev( stristr( strrev( $uri ), '/' ) );
$uri = untrailingslashit( $uri );
/** This filter is documented in wp-admin/edit-tag-form.php */
$uri = apply_filters( 'editable_slug', $uri, $post ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals
if ( ! empty( $uri ) ) {
$uri .= '/';
}
$permalink = str_replace( '%pagename%', "{$uri}%pagename%", $permalink );
}
/** This filter is documented in wp-admin/edit-tag-form.php */
$permalink = [ $permalink, apply_filters( 'editable_slug', $post->post_name, $post ) ]; // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals
$post->post_status = $original_status;
$post->post_date = $original_date;
$post->post_name = $original_name;
unset( $post->filter );
return $permalink;
}