<?php
if ( !class_exists('AutoVersioning') ) {
/**
* This class enables automatic versioning of CSS/JS by adding file modification time to the URLs.
* @see http://stackoverflow.com/questions/118884/
*/
class AutoVersioning {
private static $version_in_filename = false;
/**
* An auto-versioning wrapper for wp_register_s*() and wp_enqueue_s*() dependency APIs.
*
* @static
* @param string $wp_api_function The name of the WP dependency API to call.
* @param string $handle Script or stylesheet handle.
* @param string $src Script or stylesheet URL.
* @param array $deps Dependencies.
* @param bool|string $last_param Either $media (for wp_register_style) or $in_footer (for wp_register_script).
* @param bool $add_ver_to_filename TRUE = add version to filename, FALSE = add it to the query string.
*/
public static function add_dependency($wp_api_function, $handle, $src, $deps, $last_param, $add_ver_to_filename = false ) {
list($src, $version) = self::auto_version($src, $add_ver_to_filename);
call_user_func($wp_api_function, $handle, $src, $deps, $version, $last_param);
}
/**
* Automatically version a script or style sheet URL based on file modification time.
*
* Returns auto-versioned $src and $ver values suitable for use with WordPress dependency APIs like
* wp_register_script() and wp_register_style().
*
* @static
* @param string $url
* @param bool $add_ver_to_filename
* @return array array($url, $version)
*/
private static function auto_version($url, $add_ver_to_filename = false) {
$version = false;
$filename = self::guess_filename_from_url($url);
if ( ($filename !== null) && is_file($filename) ) {
$mtime = filemtime($filename);
if ( $add_ver_to_filename ) {
$url = preg_replace('@\.([^./\?]+)(\?.*)?$@', '.' . $mtime . '.$1', $url);
$version = null;
} else {
$version = $mtime;
}
}
return array($url, $version);
}
private static function guess_filename_from_url($url) {
static $url_mappings = null;
if ( $url_mappings === null ) {
$url_mappings = array(
plugins_url() => WP_PLUGIN_DIR,
plugins_url('', WPMU_PLUGIN_DIR . '/dummy') => WPMU_PLUGIN_DIR,
get_stylesheet_directory_uri() => get_stylesheet_directory(),
get_template_directory_uri() => get_template_directory(),
content_url() => WP_CONTENT_DIR,
site_url('/' . WPINC) => ABSPATH . WPINC,
);
}
$filename = null;
foreach($url_mappings as $root_url => $directory) {
if ( strpos($url, $root_url) === 0 ) {
$filename = $directory . '/' . substr($url, strlen($root_url));
//Get rid of the query string, if any.
list($filename, ) = explode('?', $filename, 2);
break;
}
}
return $filename;
}
/**
* Apply automatic versioning to all scripts and style sheets added using WP dependency APIs.
*
* If you set $add_ver_to_filename to TRUE, make sure to also add the following code to your
* .htaccess file or your site may break:
*
* <IfModule mod_rewrite.c>
* RewriteEngine On
* RewriteRule ^(.*)\.[\d]{10}\.(css|js)$ $1.$2 [L]
* </IfModule>
*
* @static
* @param bool $add_ver_to_filename
*/
public static function apply_to_all_dependencies($add_ver_to_filename = false) {
self::$version_in_filename = $add_ver_to_filename;
foreach(array('script_loader_src', 'style_loader_src') as $hook) {
add_filter($hook, __CLASS__ . '::_filter_dependency_src', 10, 1);
}
}
public static function _filter_dependency_src($src) {
//Only add version info to CSS/JS files that don't already have it in the file name.
if ( preg_match('@(?<!\.\d{10})\.(css|js)(\?|$)@i', $src) ) {
list($src, $version) = self::auto_version($src, self::$version_in_filename);
if ( !empty($version) ) {
$src = add_query_arg('ver', $version, $src);
}
}
return $src;
}
}
} // End of class exists check
if ( !function_exists('wp_register_auto_versioned_script') ) {
function wp_register_auto_versioned_script($handle, $src, $deps = array(), $in_footer = false, $add_ver_to_filename = false) {
AutoVersioning::add_dependency('wp_register_script', $handle, $src, $deps, $in_footer, $add_ver_to_filename);
}
}
if ( !function_exists('wp_register_auto_versioned_style') ) {
function wp_register_auto_versioned_style( $handle, $src, $deps = array(), $media = 'all', $add_ver_to_filename = false) {
AutoVersioning::add_dependency('wp_register_style', $handle, $src, $deps, $media, $add_ver_to_filename);
}
}
if ( !function_exists('wp_enqueue_auto_versioned_script') ) {
function wp_enqueue_auto_versioned_script( $handle, $src, $deps = array(), $in_footer = false, $add_ver_to_filename = false ) {
AutoVersioning::add_dependency('wp_enqueue_script', $handle, $src, $deps, $in_footer, $add_ver_to_filename);
}
}
if ( !function_exists('wp_enqueue_auto_versioned_style') ) {
function wp_enqueue_auto_versioned_style( $handle, $src, $deps = array(), $media = 'all', $add_ver_to_filename = false ) {
AutoVersioning::add_dependency('wp_enqueue_style', $handle, $src, $deps, $media, $add_ver_to_filename);
}
}