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,245 @@
<?php
namespace WP_Rocket\Addon\GoogleTracking;
use WP_Rocket\Addon\Busting\FileBustingTrait;
use WP_Rocket\Busting\Abstract_Busting;
use WP_Rocket\Logger\Logger;
/**
* Manages the cache busting of the Google Analytics file.
*
* @since 3.1
*/
class GoogleAnalytics extends Abstract_Busting {
use FileBustingTrait;
/**
* Context used for the logger.
*
* @var string
* @since 3.2.4
* @author Grégory Viguier
*/
const LOGGER_CONTEXT = 'gg analytics';
/**
* Google Analytics URL.
*
* @var string
* @since 3.1
* @access protected
* @author Remy Perona
*/
protected $url = 'https://www.google-analytics.com/analytics.js';
/**
* File name (local).
* %s is a "version": a md5 hash of the file contents.
*
* @var string
* @since 3.2.4
* @access protected
* @author Grégory Viguier
*/
protected $filename_pattern = 'ga-%s.js';
/**
* Current file version (local): a md5 hash of the file contents.
*
* @var string
* @since 3.2.4
* @access protected
* @author Grégory Viguier
*/
protected $file_version;
/**
* Flag to track the replacement.
*
* @var bool
* @since 3.1
* @access protected
* @author Remy Perona
*/
protected $is_replaced = false;
/**
* Filesystem object.
*
* @var object
* @since 3.2.4
* @access protected
* @author Grégory Viguier
*/
protected $filesystem = false;
/**
* Constructor.
*
* @since 3.1
* @access public
* @author Remy Perona
*
* @param string $busting_path Path to the busting directory.
* @param string $busting_url URL of the busting directory.
*/
public function __construct( $busting_path, $busting_url ) {
$this->busting_path = $busting_path . 'google-tracking/';
$this->busting_url = $busting_url . 'google-tracking/';
$this->filesystem = rocket_direct_filesystem();
}
/** ----------------------------------------------------------------------------------------- */
/** PUBLIC METHODS ========================================================================== */
/** ----------------------------------------------------------------------------------------- */
/**
* Performs the replacement process.
*
* @since 3.1
* @access public
* @author Remy Perona
*
* @param string $html HTML content.
* @return string
*/
public function replace_url( $html ) {
$this->is_replaced = false;
$tag = $this->find( '<script\s*(?<attr>[^>]*)?>(?<content>.*)?<\/script>', $html );
if ( ! $tag ) {
return $html;
}
Logger::info(
'GOOGLE ANALYTICS CACHING PROCESS STARTED.',
[
self::LOGGER_CONTEXT,
'tag' => $tag,
]
);
if ( ! $this->save( $this->url ) ) {
return $html;
}
$replace_tag = preg_replace( '/(?:https?:)?\/\/www\.google-analytics\.com\/analytics\.js/i', $this->get_busting_url(), $tag );
$html = str_replace( $tag, $replace_tag, $html );
$this->is_replaced = true;
Logger::info(
'Google Analytics caching process succeeded.',
[
self::LOGGER_CONTEXT,
'file' => $this->get_busting_path(),
]
);
return $html;
}
/**
* Tell if the replacement was sucessful or not.
*
* @since 3.1
* @access public
* @author Remy Perona
*
* @return bool
*/
public function is_replaced() {
return $this->is_replaced;
}
/**
* Saves the content of the URL to cache to the busting file.
*
* @since 3.2.4
* @access public
* @author Grégory Viguier
*
* @param string $url URL to get the content from.
* @return bool
*/
public function refresh_save( $url ) {
// Before doing anything, make sure the busting file can be created.
if ( ! $this->is_busting_dir_writable() ) {
return false;
}
// Get remote content.
$content = $this->get_remote_contents( $url );
if ( ! $content ) {
// Could not get the remote contents.
return false;
}
$version = md5( $content );
$path = $this->get_busting_file_path( $version );
return $this->update_file_contents( $path, $content );
}
/** ----------------------------------------------------------------------------------------- */
/** REMOTE FILE ============================================================================= */
/** ----------------------------------------------------------------------------------------- */
/**
* Get the Google Analytics URL.
*
* @since 3.1
* @access public
* @author Remy Perona
*
* @return string
*/
public function get_url() {
return $this->url;
}
/** ----------------------------------------------------------------------------------------- */
/** VARIOUS INTERNAL TOOLS ================================================================== */
/** ----------------------------------------------------------------------------------------- */
/**
* Searches for element(s) in the DOM.
*
* @since 3.1
* @access public
* @author Remy Perona
*
* @param string $pattern Pattern to match.
* @param string $html HTML content.
* @return string
*/
protected function find( $pattern, $html ) {
preg_match_all( '/' . $pattern . '/si', $html, $all_matches, PREG_SET_ORDER );
$matches = array_map(
function( $match ) {
if (
! preg_match( '/src\s*=\s*[\'"]\s*(?:https?:)?\/\/www\.google-analytics\.com\/analytics\.js\s*[\'"]/i', $match['attr'] . $match['content'] )
&&
false === strpos( $match['content'], 'GoogleAnalyticsObject' )
) {
return;
}
return $match[0];
},
$all_matches
);
$matches = array_values( array_filter( $matches ) );
if ( ! $matches ) {
return false;
}
return $matches[0];
}
}

View File

@@ -0,0 +1,200 @@
<?php
namespace WP_Rocket\Addon\GoogleTracking;
use WP_Rocket\Addon\Busting\FileBustingTrait;
use WP_Rocket\Logger\Logger;
use WP_Rocket\Busting\Abstract_Busting;
use WP_Filesystem_Direct;
/**
* Manages the cache busting of the Google Tag Manager file
*
* @since 3.1
*/
class GoogleTagManager extends Abstract_Busting {
use FileBustingTrait;
/**
* Context used for the logger.
*
* @var string
* @since 3.2.4
*/
const LOGGER_CONTEXT = 'gg tag manager';
/**
* File name (local).
* %s is a "version": a md5 hash of the file contents.
*
* @var string
* @since 3.2.4
* @access protected
*/
protected $filename_pattern = 'gtm-%s.js';
/**
* Current file version (local): a md5 hash of the file contents.
*
* @var string
* @since 3.2.4
* @access protected
*/
protected $file_version;
/**
* Filesystem object.
*
* @var object
* @since 3.2.4
* @access protected
*/
protected $filesystem = false;
/**
* Google Analytics object.
*
* @var object
* @since 3.2.4
* @access protected
*/
protected $ga_busting = false;
/**
* Constructor.
*
* @since 3.1
* @access public
*
* @param string $busting_path Path to the busting directory.
* @param string $busting_url URL of the busting directory.
* @param GoogleAnalytics $ga_busting A GoogleAnalytics instance.
* @param WP_Filesystem_Direct $filesystem Instance of the filesystem handler.
*/
public function __construct( $busting_path, $busting_url, GoogleAnalytics $ga_busting, $filesystem = null ) {
$blog_id = get_current_blog_id();
$this->busting_path = $busting_path . $blog_id . '/';
$this->busting_url = $busting_url . $blog_id . '/';
$this->ga_busting = $ga_busting;
$this->filesystem = is_null( $filesystem ) ? rocket_direct_filesystem() : $filesystem;
}
/** ----------------------------------------------------------------------------------------- */
/** PUBLIC METHODS ========================================================================== */
/** ----------------------------------------------------------------------------------------- */
/**
* Performs the replacement process.
*
* @since 3.1
* @access public
*
* @param string $html HTML content.
* @return string
*/
public function replace_url( $html ) {
$script = $this->find( '<script(\s+[^>]+)?\s+src\s*=\s*[\'"]\s*?((?:https?:)?\/\/www\.googletagmanager\.com(?:.+)?)\s*?[\'"]([^>]+)?\/?>', $html );
if ( ! $script ) {
return $html;
}
// replace relative protocol // with full https://.
$gtm_url = preg_replace( '/^\/\//', 'https://', $script[2] );
Logger::info(
'GOOGLE TAG MANAGER CACHING PROCESS STARTED.',
[
self::LOGGER_CONTEXT,
'tag' => $script,
]
);
if ( ! $this->save( $gtm_url ) ) {
return $html;
}
$replace_script = str_replace( $script[2], $this->get_busting_url(), $script[0] );
$replace_script = str_replace( '<script', '<script data-no-minify="1"', $replace_script );
$html = str_replace( $script[0], $replace_script, $html );
Logger::info(
'Google Tag Manager caching process succeeded.',
[
self::LOGGER_CONTEXT,
'file' => $this->get_busting_path(),
]
);
return $html;
}
/**
* Saves the content of the URL to cache to the busting file.
*
* @since 3.2
* @access public
*
* @param string $url URL to get the content from.
* @return bool
*/
public function refresh_save( $url ) {
// Before doing anything, make sure the busting file can be created.
if ( ! $this->is_busting_dir_writable() ) {
return false;
}
// Get remote content.
$content = $this->get_remote_contents( $url );
if ( ! $content ) {
// Could not get the remote contents.
return false;
}
$version = md5( $content );
$path = $this->get_busting_file_path( $version );
$content = $this->replace_ga_url( $content );
return $this->update_file_contents( $path, $content );
}
/** ----------------------------------------------------------------------------------------- */
/** VARIOUS INTERNAL TOOLS ================================================================== */
/** ----------------------------------------------------------------------------------------- */
/**
* Searches for element(s) in the DOM.
*
* @since 3.1
* @access public
*
* @param string $pattern Pattern to match.
* @param string $html HTML content.
* @return string
*/
protected function find( $pattern, $html ) {
preg_match_all( '/' . $pattern . '/Umsi', $html, $matches, PREG_SET_ORDER );
if ( empty( $matches ) ) {
return false;
}
return $matches[0];
}
/**
* Replaces the Google Analytics URL by the local copy inside the gtm-local.js file content
*
* @since 3.1
*
* @param string $content JavaScript content.
* @return string
*/
protected function replace_ga_url( $content ) {
if ( ! $this->ga_busting->save( $this->ga_busting->get_url() ) ) {
return $content;
}
return str_replace( $this->ga_busting->get_url(), $this->ga_busting->get_busting_url(), $content );
}
}

View File

@@ -0,0 +1,182 @@
<?php
namespace WP_Rocket\Addon\GoogleTracking;
use WP_Rocket\Event_Management\Subscriber_Interface;
use WP_Rocket\Addon\Busting\BustingFactory;
use WP_Rocket\Admin\Options_Data as Options;
/**
* Event subscriber for Google tracking cache busting
*
* @since 3.1
*/
class Subscriber implements Subscriber_Interface {
/**
* Instance of the Busting Factory class
*
* @var BustingFactory
*/
private $busting_factory;
/**
* Instance of the Option_Data class
*
* @var Options
*/
private $options;
/**
* Constructor
*
* @param BustingFactory $busting_factory Instance of the Busting Factory class.
* @param Options $options Instance of the Option_Data class.
*/
public function __construct( BustingFactory $busting_factory, Options $options ) {
$this->busting_factory = $busting_factory;
$this->options = $options;
}
/**
* Return an array of events that this subscriber wants to listen to.
*
* @since 3.1
*
* @return array
*/
public static function get_subscribed_events() {
$events = [
'cron_schedules' => 'add_schedule',
'init' => 'schedule_tracking_cache_update',
'rocket_google_tracking_cache_update' => 'update_tracking_cache',
'rocket_purge_cache' => 'delete_tracking_cache',
'rocket_buffer' => 'cache_busting_google_tracking',
];
return $events;
}
/**
* Processes the cache busting on the HTML content
*
* Google Analytics replacement is performed first, and if no replacement occured, Google Tag Manager replacement is performed.
*
* @since 3.1
*
* @param string $html HTML content.
* @return string
*/
public function cache_busting_google_tracking( $html ) {
if ( ! $this->is_allowed() ) {
return $html;
}
$processor = $this->busting_factory->type( 'ga' );
$html = $processor->replace_url( $html );
$processor = $this->busting_factory->type( 'gtm' );
$html = $processor->replace_url( $html );
return $html;
}
/**
* Schedules the auto-update of Google Analytics cache busting file
*
* @since 3.1
*
* @return void
*/
public function schedule_tracking_cache_update() {
if ( ! $this->is_busting_active() ) {
return;
}
if ( ! wp_next_scheduled( 'rocket_google_tracking_cache_update' ) ) {
wp_schedule_event( time(), 'weekly', 'rocket_google_tracking_cache_update' );
}
}
/**
* Updates Google Analytics cache busting file
*
* @since 3.1
*
* @return bool
*/
public function update_tracking_cache() {
if ( ! $this->is_busting_active() ) {
return false;
}
$processor = $this->busting_factory->type( 'ga' );
return $processor->refresh_save( $processor->get_url() );
}
/**
* Adds weekly interval to cron schedules
*
* @since 3.1
*
* @param Array $schedules An array of intervals used by cron jobs.
* @return Array
*/
public function add_schedule( $schedules ) {
if ( ! $this->is_busting_active() ) {
return $schedules;
}
$schedules['weekly'] = [
'interval' => 604800,
'display' => __( 'weekly', 'rocket' ),
];
return $schedules;
}
/**
* Deletes the GA busting file.
*
* @since 3.1
* @since 3.6 Argument replacement.
*
* @param string $type Type of cache clearance: 'all', 'post', 'term', 'user', 'url'.
* @return bool
*/
public function delete_tracking_cache( $type ) {
if ( 'all' !== $type || ! $this->is_busting_active() ) {
return false;
}
$this->busting_factory->type( 'gtm' )->delete();
return $this->busting_factory->type( 'ga' )->delete();
}
/**
* Checks if the cache busting should happen
*
* @since 3.1
*
* @return boolean
*/
private function is_allowed() {
if ( rocket_get_constant( 'DONOTROCKETOPTIMIZE' ) ) {
return false;
}
return $this->is_busting_active();
}
/**
* Tell if the cache busting option is active.
*
* @since 3.6
*
* @return bool
*/
private function is_busting_active() {
return (bool) $this->options->get( 'google_analytics_cache', 0 );
}
}