array(), 'footer' => array() ); /** Wordpress to_do scripts, used both by mergescripts and admin_bar */ private $to_do; /** Used for save the handles want to deregister both by mmergeScripts and checkCache method */ private $deregister = array('style' => array(), 'script' => array()); /** Handles that ara not detected by wp_print_scripts, we get it from wp_header and wp_footer we compare the rest_of_handles option with the registered handles generated by wordpress */ private $restOfHandles = array('header' => array(), 'footer' => array()); /** Check whether the method is already executed. This is to prevent the method from executed by other plugins */ private $isExecuted = array('merge_styles' => false, 'merge_scripts' => false, 'footer_scripts' => false, 'header_scripts' => false ); public function __construct () { $this->options = get_option(APHMS_OPTION); } public function init() { add_action('init', array($this, 'runPlugin')); } public function runPlugin() { $admin_bar = is_admin_bar_showing(); if (is_admin() || (is_user_logged_in() && !$admin_bar) || ($admin_bar && $this->options['manage_scripts'])) { return; } if (isset($this->options['merge_scripts'])) { add_action( 'wp_print_scripts', array( $this, 'mergeScripts' ), 999 ); add_action( 'wp_head', array( $this, 'deregisterScript' ), 7 ); add_action( 'wp_footer', array( $this, 'deregisterScript' ) ); } if (isset($this->options['merge_styles'])) { add_action( 'wp_print_styles', array( $this, 'mergeStyles' ), 10 ); } } public function mergeStyles() { if ($this->isExecuted['merge_styles']) return; if (!$this->options['merge_styles']) return; global $wp_styles; $queues = $wp_styles->queue; $wp_styles->all_deps($queues); $this->to_do = $wp_styles->to_do; //File Name $file = AphmsHelper::mergeFilePath('style'); $use_cache = $this->checkCache('style'); if (!$use_cache) { $merged_style = ''; $list_handles = array(); foreach( $this->to_do as $handle) { if (!key_exists($handle, $wp_styles->registered)) continue; $file_path = $this->filePath($wp_styles->registered[$handle]->src); if (file_exists($file_path)) { $list_handles[] = $handle; $this->deregister['style'][] = $handle; $minifier = new Minify\CSS($file_path); $minifier->setToPath( $file['file_path'] ); $merged_style .= $minifier->minify(); } } if ($merged_style) { file_put_contents($file['file_path'], '/* APH Merge Scripts v'.APHMS_PLUGIN_VERSION.' | Date ' . date('Y-m-d H:i:s') . ' | Handles: ' . join($list_handles, ', ') . ' */' . "\r\n" . $merged_style); } // update current handles $this->options['curr_handles']['style']['time'] = time(); $this->options['curr_handles']['style']['handles'] = $list_handles; update_option(APHMS_OPTION, $this->options); } foreach ($this->deregister['style'] as $handle) { wp_deregister_style($handle); } $time = $this->options['force_use_newest_style'] ? '?rand=' . time() : ''; wp_enqueue_style('merged-script', $file['file_url'] . $time, '', APHMS_PLUGIN_VERSION); $this->isExecuted['merge_styles'] = true; } public function mergeScripts($position) { if ($this->isExecuted['merge_scripts']) return; if ($this->options['merge_scripts'] == 'donot-merge') return; global $wp_scripts; $aphms_scripts = $wp_scripts; $queues = $wp_scripts->queue; $aphms_scripts->all_deps($queues); $this->to_do = $aphms_scripts->to_do; /* Used for either merged path or enqueue url */ $file = AphmsHelper::mergeFilePath('script'); // Check cache $use_cache = $this->checkCache('script'); // $use_cached = false; if (!$use_cache) { $merged_script = ''; $list_handles = array(); // Loop javascript files and save to $merged_script variable foreach( $this->to_do as $handle) { if ($this->skipHandle($handle) || !key_exists($handle, $aphms_scripts->registered)) continue; $obj = $aphms_scripts->registered[$handle]; // wp_localize_script $localize = ''; if (@key_exists('data', $obj->extra)) $localize = $obj->extra['data'] . ';'; $file_path = $this->filePath($obj->src); if (file_exists($file_path)) { $list_handles[] = $handle; $merged_script .= '/* Handle: ' . $handle . ' */' . "\r\n\r\n" . $localize . file_get_contents($file_path) . ';' . "\r\n\r\n"; $this->deregister['script'][] = $handle; } } // Merge rest of scripts foreach( $this->options['rest_of_handles']['script'] as $pos => $handles) { foreach ($handles as $handle => $arr) { if (in_array($handle, $this->to_do) || $this->skipHandle($handle)) continue; // wp_localize_script $localize = ''; if (@key_exists('data', $arr['extra'])) $localize = $arr['extra']['data'] . ';'; $file_path = $this->filePath($arr['src']); if (file_exists($file_path)) { $list_handles[] = $handle; $merged_script .= '/* Handle: ' . $handle . ' */' . "\r\n\r\n" . $localize . file_get_contents($file_path) . ';' . "\r\n\r\n"; $this->deregister['script'][] = $handle; } } } // Save $merged_script as a file if ($merged_script) { if ($this->options['minify_script']) { $minifier = new Minify\JS($merged_script); $merged_script = $minifier->minify(); } $cache = $use_cache ? 'Yes' : 'No'; file_put_contents($file['file_path'], '/* APH Merge Scripts v'.APHMS_PLUGIN_VERSION.' | Date ' . date('Y-m-d H:i:s') . ' | Handles: ' . join($list_handles, ', ') . ' */' . "\r\n" . $merged_script); } // update current handles $this->options['curr_handles']['script']['time'] = time(); $this->options['curr_handles']['script']['handles'] = $list_handles; update_option(APHMS_OPTION, $this->options); } foreach ($this->deregister['script'] as $handle) { wp_deregister_script($handle); } $location = $this->options['merge_scripts'] == 'merge-footer' ? true : false; $time = $this->options['force_use_newest_script'] ? '?rand=' . time() : ''; wp_enqueue_script('merged-script', $file['file_url'] . $time, '', APHMS_PLUGIN_VERSION, $location); $this->isExecuted['merge_scripts'] = true; } /** Check cache make sure that all handles are processed */ private function checkCache($type) { if (!$this->options['curr_handles'][$type]['time'] || !$this->options['curr_handles'][$type]['handles'] ) return false; // Chech whether the merged file exists $file = AphmsHelper::mergeFilePath($type); if (!file_exists($file['file_path'])) return false; $date = $this->options['curr_handles'][$type]['time']; $expired = strtotime('+'.$this->options['cache_age'].' day', $date); if ($date > $expired) return false; $use_cache = true; $list_of_handles = array_merge($this->to_do, array_keys($this->options['rest_of_handles'][$type]['header']), array_keys($this->options['rest_of_handles'][$type]['footer']) ); foreach($list_of_handles as $handle) { if (!in_array($handle, $this->options['curr_handles'][$type]['handles'])) { $use_cache = false; } $deregister[] = $handle; } if ($use_cache) $this->deregister[$type] = $deregister; return $use_cache; } /** File path Find relative path of each style or script */ private function filePath($src) { $clean_hash = $clean = strtok($src,'?'); $site_url = site_url(); $parse_site_url = parse_url($site_url); $parse_url = parse_url($clean_hash); $site_path = ''; if (key_exists('path', $parse_site_url)) { $site_path = $parse_site_url['path']; } if (key_exists('host', $parse_url)) { // Exclude external script if ($parse_site_url['host'] != $parse_url['host']) return false; $file_path = substr ($parse_url['path'], strlen($site_path)); $file_path = ltrim ($file_path, '/'); } else { $file_path = ltrim($parse_url['path'], '/'); } return $file_path; } private function skipHandle($handle) { $excluded_script = $this->options['excluded_handles']; if (in_array($handle, $excluded_script)) return true; else return false; } /** Used in the init method to deregister th scripts earlier */ public function deregisterScript() { foreach( $this->options['rest_of_handles']['script'] as $pos => $handles) { foreach ($handles as $handle => $arr) { wp_deregister_script($handle); } } } }