plugin = $plugin;
$this->_header_scripts = null;
$this->_footer_scritps = null;
add_filter('script_loader_tag', array($this, 'script_loader_tag'), 10, 3 );
add_filter('wp_print_scripts', array($this, 'just_in_time_scripts'), 9999);
add_action('wp_print_scripts', array($this, 'scripts_data_head'), 0);
add_action('wp_print_footer_scripts', array($this, 'scripts_data_footer'), 0);
}
/**
* @param $tag
* @param $handle
* @param $src
*
* @return string
*/
function script_loader_tag($tag, $handle, $src){
$additional = '';
switch($handle){
case Plugin::HANDLE_HEADER:
$additional = get_option(Plugin::OPTION_HEADER_SCRIPT_ATTRIBUTES, '');
break;
case Plugin::HANDLE_FOOTER:
$additional = get_option(Plugin::OPTION_FOOTER_SCRIPT_ATTRIBUTES, '');
break;
}
if($additional != ''){
return "";
}
return $tag;
}
/**
* Latest point of script manipulation
* @param $arg
*
* @return mixed
*/
function just_in_time_scripts($arg){
if(!is_admin()){
// aggregate frontend js files
$this->scripts();
}
return $arg;
}
/**
* render header data script info
*/
function scripts_data_head() {
$header = $this->get_header_scripts();
echo "\n\n";
$this->_render_script_data( $header );
echo "\n\n";
}
/**
* render footer data script info
*/
function scripts_data_footer() {
$footer = $this->get_footer_scripts();
echo "\n\n";
$this->_render_script_data( $footer );
echo "\n\n";
}
/**
* script data javascript
* @param $scripts
*/
private function _render_script_data( $scripts ) {
foreach ( $scripts as $script ) {
if ( $script->extra_data == null || $script->extra_data == "" ) {
continue;
}
$extra = $script->extra_data;
?>
get_header_scripts();
$header_filename = $this->get_js_filename( $header );
if ( ! $this->plugin->file_handler->file_exists( $header_filename ) ) {
// aggregate new header js
$this->plugin->file_handler->aggregate_and_write( $header_filename, $header );
}
$footer = $this->get_footer_scripts();
$footer_filename = $this->get_js_filename( $footer );
if ( ! $this->plugin->file_handler->file_exists( $footer_filename ) ) {
// aggregate new footer js
$this->plugin->file_handler->aggregate_and_write( $footer_filename, $footer );
}
/*
* enqueue aggregated files
*/
wp_enqueue_script(
Plugin::HANDLE_HEADER,
$this->plugin->file_handler->paths()->url . "/{$header_filename}",
null,
filemtime( $this->plugin->file_handler->paths()->dir . "/{$header_filename}" ),
false
);
wp_enqueue_script(
Plugin::HANDLE_FOOTER,
$this->plugin->file_handler->paths()->url . "/{$footer_filename}",
null,
filemtime( $this->plugin->file_handler->paths()->dir . "/{$footer_filename}" ),
true
);
/*
* dequeue scripts
*/
$this->dequeue( $header );
$this->dequeue( $footer );
}
/**
* @param $scripts array of script objects
*
* @return string
*/
function get_js_filename( $scripts ) {
$ids = array();
$post_fix = "";
$prefix = "";
foreach ( $scripts as $script ) {
$ids[] = "{$script->handle}-{$script->url}-{$script->changed}";
$post_fix = ( $script->footer ) ? self::FILENAME_SUFFIX_FOOTER : self::FILENAME_SUFFIX_HEADER;
$prefix = ($script->footer)? "f": "h";
}
return $prefix.sha1( implode( '--', $ids ) ) . "{$post_fix}.js";
}
/**
* @param bool $footer
*
* @return array
*/
private function _get_scripts( $footer = true ) {
return array_filter( $this->get_scripts(), function ( $value, $key ) use ( $footer ) {
return $value->footer == $footer;
}, ARRAY_FILTER_USE_BOTH );
}
/**
* get all footer scripts for aggregator
* @return array
*/
function get_footer_scripts() {
if ( $this->_footer_scritps == null ) {
$this->_footer_scritps = $this->_get_scripts( true );
}
return $this->_footer_scritps;
}
/**
* get all header scripts for aggregator
* @return array
*/
function get_header_scripts() {
if ( $this->_header_scripts == null ) {
$this->_header_scripts = $this->_get_scripts( false );
}
return $this->_header_scripts;
}
/**
* get all scripts for aggregator
* @return array
*/
function get_scripts() {
global $wp_scripts;
if ( ! is_a( $wp_scripts, "WP_Scripts" ) ) {
return array();
}
$scripts = array();
if ( is_array( $wp_scripts->queue ) ) {
$blog_info_url = get_bloginfo( 'url' );
$blog_domain = str_replace( array( 'https://', 'http://', '//' ), '', $blog_info_url );
/*
* resolve dependencies
*/
$wp_scripts->all_deps( $wp_scripts->queue );
foreach ( $wp_scripts->to_do as $js ) {
// TODO: Remove deprecated get_ignores() call in future version.
if ( $this->is_ignored( $js ) || in_array( $js, $this->get_ignores() ) ) {
continue;
}
if ( ! empty( $wp_scripts->registered[ $js ] ) ) {
$script = $wp_scripts->registered[ $js ];
if ( !$script->src ) continue;
$obj = (object) array(
'raw' => $script,
'handle' => $js,
'src' => $script->src,
'file_path' => null,
'url' => null,
'footer' => false,
'changed' => '',
'extra_data' => null,
'external' => false,
);
$src = $obj->src;
// parse_url cannot use protocol relatives
if(strpos($src, "//") === 0){
$src = "http:$src";
}
$parsed = parse_url($src);
if( !isset($parsed["host"]) && !empty($parsed["path"]) ){
// no host. just path on our own site
$guessed_path = ABSPATH . $parsed["path"];
if(file_exists($guessed_path)){
$obj->file_path = $guessed_path;
}
} else if(!empty($parsed["host"]) && !empty($parsed["path"])){
// is it own domain? we can try file path
$guessed_path = ABSPATH . $parsed["path"];
$port = (isset($parsed["port"]))? $parsed["port"]:"";
if ( ( $parsed["host"] == $blog_domain || $parsed["host"].":$port" == $blog_domain )
&& file_exists($guessed_path)) {
$obj->file_path = $guessed_path;
} else {
// fallback load via http check
$ch = curl_init($src);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_TIMEOUT,10);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if($http_code == 200){
$obj->url = $src;
}
}
}
// if cannot resolve source skip it!
if($obj->url == null && $obj->file_path == null) continue;
if ( is_array( $script->extra ) ) {
$extra = $script->extra;
/*
* is in footer group
*/
if ( isset( $extra["group"] ) && $extra['group'] == 1 ) {
$obj->footer = true;
}
/*
* has extra data like localization
*/
if ( isset( $extra["data"] ) && is_string( $extra['data'] ) ) {
$obj->extra_data = $extra["data"];
}
}
/*
* check file time
*/
if ( file_exists( $obj->file_path ) ) {
$obj->changed = filemtime( $obj->file_path );
}
$scripts[ $js ] = $obj;
}
}
}
return $scripts;
}
/**
* dequeue scripts
*
* @param $scripts
*
*/
function dequeue( $scripts ) {
global $wp_scripts;
if ( ! is_array( $wp_scripts->queue ) ) {
return;
}
$wp_scripts->all_deps( $wp_scripts->queue );
for ( $i = 0; $i < count( $wp_scripts->to_do ); $i ++ ) {
$handle = $wp_scripts->to_do[ $i ];
foreach($scripts as $script){
if($handle == $script->handle){
wp_dequeue_script( $handle );
$wp_scripts->remove( $handle );
array_splice( $wp_scripts->to_do, $i, 1 );
$i --;
}
}
}
}
/**
* @param $js_handle
*
* @return bool
*/
function is_ignored( $js_handle ) {
return apply_filters( Plugin::FILTER_IGNORE_FILE, false, $js_handle );
}
/**
* get js to ignore while aggregating
* @return array
*/
function get_ignores() {
return apply_filters( Plugin::FILTER_IGNORED_FILES, array() );
}
}