essb_cache_static_objects( $wp_scripts, $todo, 'js' ); } function init_essb_cache_static_css( $todo ) { global $wp_styles; return $this->essb_cache_static_objects( $wp_styles, $todo, 'css' ); } function essb_cache_static_objects( &$object, $todo, $extension ) { // Don't run if on admin or already processed if ( is_admin() || empty( $todo ) ) return $todo; // Allow files to be excluded from ESSBCacheStaticResources $essb_cache_static_exclude = (array) apply_filters( 'essb_cache_static-exclude-' . $extension, array() ); // Exluce all essb_cache_static items by default $essb_cache_static_exclude = array_merge( $essb_cache_static_exclude, $this->get_done() ); $essb_cache_static_todo = array_diff( $todo, $essb_cache_static_exclude ); if ( empty( $essb_cache_static_todo ) ) return $todo; $done = array(); $ver = array(); // Bust cache on ESSBCacheStaticResources plugin update $ver[] = 'essb_cache_static-ver-1.0.0'; // Debug enable // $ver[] = 'debug-' . time(); // Use different cache key for SSL and non-SSL $ver[] = 'is_ssl-' . is_ssl(); // Use a global cache version key to purge cache $ver[] = 'essb_cache_static_cache_ver-' . get_option( 'essb_cache_static_cache_ver' ); // Use script version to generate a cache key foreach ( $essb_cache_static_todo as $t => $script ) $ver[] = sprintf( '%s-%s', $script, $object->registered[ $script ]->ver ); $cache_ver = md5( 'essb_cache_static-' . implode( '-', $ver ) . $extension ); // Try to get queue from cache $cache = get_transient( 'essb_cache_static-' . $cache_ver ); if ( isset( $cache['cache_ver'] ) && $cache['cache_ver'] == $cache_ver && file_exists( $cache['file'] ) ) return $this->essb_cache_static_enqueue_files( $object, $cache ); foreach ( $essb_cache_static_todo as $script ) { $pos_easy_social = strpos($script, 'easy-social-'); $pos_essb = strpos($script, 'essb'); if ($pos_easy_social === false && $pos_essb === false) { continue; } // Get the relative URL of the asset $src = self::get_asset_relative_path( $object->base_url, $object->registered[ $script ]->src ); // Add support for pseudo packages such as jquery which return src as empty string if ( empty( $object->registered[ $script ]->src ) || '' == $object->registered[ $script ]->src ) $done[ $script ] = null; // Skip if the file is not hosted locally if ( ! $src || ! file_exists( ABSPATH . $src ) ) continue; $script_content = apply_filters( 'essb_cache_static-item-' . $extension, file_get_contents( ABSPATH . $src ), $object, $script ); if ( false !== $script_content ) { if ($extension == "css") { $script_content = trim(preg_replace('/\s+/', ' ', $script_content)); } $done[ $script ] = $script_content; } } if ( empty( $done ) ) return $todo; $wp_upload_dir = wp_upload_dir(); // Try to create the folder for cache if ( ! is_dir( $wp_upload_dir['basedir'] . '/essb_cache_static' ) ) if ( ! mkdir( $wp_upload_dir['basedir'] . '/essb_cache_static' ) ) return $todo; $combined_file_path = sprintf( '%s/essb_cache_static/%s.%s', $wp_upload_dir['basedir'], $cache_ver, $extension ); $combined_file_url = sprintf( '%s/essb_cache_static/%s.%s', $wp_upload_dir['baseurl'], $cache_ver, $extension ); // Allow other plugins to do something with the resulting URL $combined_file_url = apply_filters( 'essb_cache_static-url-' . $extension, $combined_file_url, $done ); // Allow other plugins to minify and obfuscate $done_imploded = apply_filters( 'essb_cache_static-content-' . $extension, implode( "\n\n", $done ), $done ); // Store the combined file on the filesystem if ( ! file_exists( $combined_file_path ) ) if ( ! file_put_contents( $combined_file_path, $done_imploded ) ) return $todo; $status = array( 'cache_ver' => $cache_ver, 'todo' => $todo, 'done' => array_keys( $done ), 'url' => $combined_file_url, 'file' => $combined_file_path, 'extension' => $extension ); // Cache this set of scripts for 24 hours set_transient( 'essb_cache_static-' . $cache_ver, $status, YEAR_IN_SECONDS ); $this->set_done( $cache_ver ); return $this->essb_cache_static_enqueue_files( $object, $status ); } function essb_cache_static_enqueue_files( &$object, $status ) { extract( $status ); switch ( $extension ) { case 'css': wp_enqueue_style( 'essb_cache_static-' . $cache_ver, $url, null, null ); // Add inline styles for all essb_cache_staticed styles foreach ( $done as $script ) { $inline_style = $object->get_data( $script, 'after' ); if ( ! empty( $inline_style ) ) $object->add_inline_style( 'essb_cache_static-' . $cache_ver, $inline_style ); } break; case 'js': wp_enqueue_script( 'essb_cache_static-' . $cache_ver, $url, null, null, apply_filters( 'essb_cache_static-js-in-footer', true ) ); // Add to the correct $object->set_group( 'essb_cache_static-' . $cache_ver, false, apply_filters( 'essb_cache_static-js-in-footer', true ) ); $inline_data = array(); // Add inline scripts for all essb_cache_staticed scripts foreach ( $done as $script ) $inline_data[] = $object->get_data( $script, 'data' ); // Filter out empty elements $inline_data = array_filter( $inline_data ); if ( ! empty( $inline_data ) ) $object->add_data( 'essb_cache_static-' . $cache_ver, 'data', implode( "\n", $inline_data ) ); break; default: return $todo; } // Remove scripts that were merged $todo = array_diff( $todo, $done ); $todo[] = 'essb_cache_static-' . $cache_ver; // Mark these items as done $object->done = array_merge( $object->done, $done ); // Remove ESSBCacheStaticResources items from the queue $object->queue = array_diff( $object->queue, $done ); return $todo; } function set_done( $handle ) { $this->essb_cache_static_done[] = 'essb_cache_static-' . $handle; } function get_done() { return $this->essb_cache_static_done; } public static function get_asset_relative_path( $base_url, $item_url ) { // Remove protocol reference from the local base URL $base_url = preg_replace( '/^(https?:\/\/|\/\/)/i', '', $base_url ); // Check if this is a local asset which we can include $src_parts = explode( $base_url, $item_url ); // Get the trailing part of the local URL $maybe_relative = end( $src_parts ); if ( ! file_exists( ABSPATH . $maybe_relative ) ) return false; return $maybe_relative; } public function async_init() { global $wp_scripts; if ( ! is_object( $wp_scripts ) || empty( $wp_scripts->queue ) ) return; $base_url = site_url(); $essb_cache_static_exclude = (array) apply_filters( 'essb_cache_static-exclude-js', array() ); foreach ( $wp_scripts->queue as $handle ) { // Skip asyncing explicitly excluded script handles if ( in_array( $handle, $essb_cache_static_exclude ) ) { continue; } $script_relative_path = ESSBStaticCache::get_asset_relative_path( $base_url, $wp_scripts->registered[$handle]->src ); if ( ! $script_relative_path ) { // Add this script to our async queue $this->async_queue[] = $handle; // Remove this script from being printed the regular way wp_dequeue_script( $handle ); } } } public function async_print() { global $wp_scripts; if ( empty( $this->async_queue ) ) return; ?> registered[ $script ]->src ) . $content; } // Add table of contents at the top of the ESSBCacheStaticResources file add_filter( 'essb_cache_static-content-css', 'essb_cache_static_add_toc', 100, 2 ); add_filter( 'essb_cache_static-content-js', 'essb_cache_static_add_toc', 100, 2 ); function essb_cache_static_add_toc( $content, $items ) { if ( ! $content || empty( $items ) ) return $content; $toc = array(); foreach ( $items as $handle => $item_content ) $toc[] = sprintf( ' - %s', $handle ); return sprintf( "/* TOC:\n%s\n*/", implode( "\n", $toc ) ) . $content; } // Turn all local asset URLs into absolute URLs add_filter( 'essb_cache_static-item-css', 'essb_cache_static_resolve_css_urls', 10, 3 ); function essb_cache_static_resolve_css_urls( $content, $object, $script ) { if ( ! $content ) return $content; $src = ESSBStaticCache::get_asset_relative_path( $object->base_url, $object->registered[ $script ]->src ); // Make all local asset URLs absolute $content = preg_replace( '/url\(["\' ]?+(?!data:|https?:|\/\/)(.*?)["\' ]?\)/i', sprintf( "url('%s/$1')", $object->base_url . dirname( $src ) ), $content ); return $content; } // Add support for relative CSS imports add_filter( 'essb_cache_static-item-css', 'essb_cache_static_resolve_css_imports', 10, 3 ); function essb_cache_static_resolve_css_imports( $content, $object, $script ) { if ( ! $content ) return $content; $src = ESSBStaticCache::get_asset_relative_path( $object->base_url, $object->registered[ $script ]->src ); // Make all import asset URLs absolute $content = preg_replace( '/@import\s+(url\()?["\'](?!https?:|\/\/)(.*?)["\'](\)?)/i', sprintf( "@import url('%s/$2')", $object->base_url . dirname( $src ) ), $content ); return $content; } // Exclude styles with media queries from being included in ESSBCacheStaticResources add_filter( 'essb_cache_static-item-css', 'essb_cache_static_exclude_css_with_media_query', 10, 3 ); function essb_cache_static_exclude_css_with_media_query( $content, $object, $script ) { if ( ! $content ) return $content; $whitelist = array( '', 'all', 'screen' ); // Exclude from ESSBCacheStaticResources if media query specified if ( ! in_array( $object->registered[ $script ]->args, $whitelist ) ) return false; return $content; } // Make sure that all ESSBCacheStaticResources files are served from the correct protocol add_filter( 'essb_cache_static-url-css', 'essb_cache_static_maybe_ssl_url' ); add_filter( 'essb_cache_static-url-js', 'essb_cache_static_maybe_ssl_url' ); function essb_cache_static_maybe_ssl_url( $url ) { if ( is_ssl() ) return str_replace( 'http://', 'https://', $url ); return $url; } // Add a Purge Cache link to the plugin list //add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), 'essb_cache_static_cache_purge_admin_link' ); //function essb_cache_static_cache_purge_admin_link( $links ) { // $links[] = sprintf( // '%s', // wp_nonce_url( add_query_arg( 'purge_essb_cache_static', true ), 'purge_essb_cache_static' ), // __( 'Purge cache', 'essb_cache_static' ) // ); // return $links; //} /** * Maybe purge essb_cache_static cache */ //add_action( 'admin_init', 'purge_essb_cache_static_cache' ); function purge_essb_cache_static_cache() { //if ( ! isset( $_GET['purge_essb_cache_static'] ) ) // return; //if ( ! check_admin_referer( 'purge_essb_cache_static' ) ) // return; // Use this as a global cache version number update_option( 'essb_cache_static_cache_ver', time() ); purge_essb_cache_static_transients(); add_action( 'admin_notices', 'essb_cache_static_cache_purged_success' ); // Allow other plugins to know that we purged do_action( 'essb_cache_static-cache-purge-delete' ); } // @since 2.0.3 Clearing transients function purge_essb_cache_static_transients() { global $wpdb; $time_now = time(); $expired = $wpdb->get_col( "SELECT option_name FROM $wpdb->options where (option_name LIKE '_transient_timeout_essb_cache_static-%') OR (option_name LIKE '_transient_essb_cache_static-%')" ); //print_r($expired); if( empty( $expired ) ) { return false; } foreach( $expired as $transient ) { $name = str_replace( '_transient_timeout_', '', $transient ); $name = str_replace( '_transient_', '', $transient ); delete_transient( $name ); } return true; } function essb_cache_static_cache_purged_success() { printf( '
%s