1, 'minify_style' => 1, 'style_location' => 'default', 'style_file_name' => 'merged_style.css', 'style_query_string' => 0, // Scripts 'merge_scripts' => 1, 'minify_script' => 1, 'script_location' => 'default', 'script_file_name' => 'merged_script.js', 'cache_age' => 1, 'manage_scripts' => 0, 'script_query_string' => 0, // CDN 'remote_files' => 3, 'remote_files_age' => 30, // day 'request_timeout' => 10, // sec // Optiond 'run_on_404' => 0 ); /** Additional options that do not include in the admin form. We use it on the admin bar section. We use wordpress settings API so when we save the options, only input elements that have name attribute will be pass the value, and overwrite the existing options. */ private $add_options = array( 'excluded_handles' => array('merged-script' => 'merged-script'), 'rest_of_handles' => array('script' => array( 'header' => array(), 'footer' => array() ), 'style' => array( 'header' => array(), 'footer' => array() ) ), // Current handles used to build the merged file (.js or .css), useful if we use the cache option 'curr_handles' => array('style' => array('time' => '', 'handles' => '') , 'script' => array('time' => '', 'handles' => '') ), 'remote_handles' => array('style' => array(), 'script' => array() ) ); /** * Start up */ public function __construct() { $this->options = get_option( APHMS_OPTION, array() ); $this->admin_notices = new Aphms_Admin_Notices; register_activation_hook ( APHMS_PLUGIN_PATH . APHMS_DS . APHMS_PLUGIN_FILE_NAME, array($this, 'activate_plugin') ); register_deactivation_hook ( APHMS_PLUGIN_PATH . APHMS_DS . APHMS_PLUGIN_FILE_NAME, array($this, 'deactivate_plugin') ); add_action( 'wp_ajax_aphms-check-exec', array($this, 'ajax_check_exec') ); add_filter( 'plugin_action_links', array($this, 'action_link'), 10, 5); add_action( 'admin_enqueue_scripts', array($this, 'register_scripts') ); add_action( 'admin_menu', array( $this, 'add_plugin_page' ) ); add_action( 'admin_init', array( $this, 'page_init' ) ); } public function deactivate_plugin() { // Clear cache array_map('unlink', glob(APHMS_PLUGIN_PATH . APHMS_DS . 'merged/*.*')); } public function activate_plugin() { $data = array_merge ($this->data, $this->add_options); $plugin_version = get_option( APHMS_OPTION_VERSION, array() ); if ($this->options) { if (!$plugin_version) { $new_opt = array(); if (key_exists('merge_styles', $this->options)) { $this->options['minify_style'] = 1; } else { $new_opt['merge_styles'] = 0; $new_opt['minify_style'] = 1; } if ($this->options['merge_scripts'] == 'merge-header') $this->options['merge_scripts'] = 1; else if ($this->options['merge_scripts'] == 'merge-footer') $this->options['merge_scripts'] = 2; else if ($this->options['merge_scripts'] == 'donot-merge') $this->options['merge_scripts'] = 0; if (!key_exists('minify_script', $this->options)) { $new_opt['minify_script'] = 0; } if (key_exists('force_use_newest_style', $this->options)) { unset($this->options['force_use_newest_style']); } $new_opt['style_query_string'] = 0; if (key_exists('force_use_newest_script', $this->options)) { unset($this->options['force_use_newest_script']); } $new_opt['script_query_string'] = 0; $new_options = array_merge($new_opt, $this->options); update_option(APHMS_OPTION, $new_options); update_option(APHMS_OPTION_VERSION, APHMS_PLUGIN_VERSION); } else { if (version_compare('1.3', $plugin_version) > 0) { $this->options['remote_handles'] = array('style' => array(), 'script' => array() ); $this->options['remote_files'] = 3; $this->options['remote_files_age'] = 30; $this->options['request_timeout'] = 10; $this->options['run_on_404'] = 0; update_option(APHMS_OPTION, $this->options); update_option(APHMS_OPTION_VERSION, APHMS_PLUGIN_VERSION); } } } else { update_option(APHMS_OPTION, $data); update_option(APHMS_OPTION_VERSION, APHMS_PLUGIN_VERSION); } } /** * Add Settings ling to plugin list Settings | Deactivate | Edit */ public function action_link($links, $file) { static $plugin; if (!isset($plugin)) $plugin = APHMS_PLUGIN_DIR_NAME . '/' . APHMS_PLUGIN_FILE_NAME; // echo $plugin; die; if ($plugin == $file) { $setting_link = 'Settings'; array_unshift($links, $setting_link); } return $links; } /** * Add options page */ public function add_plugin_page() { // This page will be under "Settings" $page_title = 'APH Merge Scripts Options'; $menu_title = 'APH Merge Scripts'; add_options_page( $page_title, $menu_title, 'manage_options', 'aph-merge-scripts', array( $this, 'admin_page' ) ); } /** * Options page callback */ public function admin_page() { ?>

Options

APH Merge Scripts Options

wp_create_nonce('aphms-check-exec') ) ); } public function page_init() { if (isset($_GET['_wpnonce']) && wp_verify_nonce($_GET['_wpnonce'], 'aphms_clear_cache') ) $this->delete_cache(); if (isset($_GET['_wpnonce']) && wp_verify_nonce($_GET['_wpnonce'], 'aphms_clear_local_copy') ) $this->clear_local_copy(); register_setting( 'aph_merge_group', // Option group APHMS_OPTION, array ($this, 'submit_validation')// Option name ); // Merge Style Options add_settings_section('option_page', 'Merge CSS Files', '__return_true', 'style_options'); add_settings_field('style_merge', 'Merge & Minify CSS Files', array($this, 'style_options'), 'style_options', 'option_page'); // Merge Script Options add_settings_section('option_page', 'Merge Javascript Files', '__return_true', 'script_options'); add_settings_field('script_merge', 'Merge & Minify Scripts', array($this, 'script_options'), 'script_options', 'option_page'); // Remote Files Options add_settings_section('option_page', 'Remote (CDN) File Options', '__return_true', 'remote_options'); add_settings_field('remote_files', 'Remote Files', array($this, 'remote_files'), 'remote_options','option_page'); add_settings_field('request_timeout', 'Request Timeout', array($this, 'request_timeout'), 'remote_options', 'option_page'); add_settings_field('local_copy', 'Local Copy', array($this, 'local_copy'), 'remote_options', 'option_page'); // General Options add_settings_section('option_page', 'General Options', '__return_true', 'general_options'); add_settings_field('cache_age', 'Cache Age', array($this, 'cache_age'), 'general_options', 'option_page'); add_settings_field('run_on_404', 'Run on 404 Page', array($this, 'run_on_404'), 'general_options', 'option_page'); add_settings_field('manage_scripts', 'Manage Scripts', array($this, 'manage_scripts'), 'general_options', 'option_page'); add_settings_field('clear_cache', 'Clear All Cache', array($this, 'clear_cache_options'), 'general_options', 'option_page'); add_settings_field('excluded_handles', 'Excluded Handles', array($this, 'excluded_handles'), 'general_options', 'option_page'); } public function style_options() { $checked_query_string = $this->options['style_query_string'] ? ' checked="checked"' : ''; ?>

'Do not merge', 1 => 'Merge all CSS files');?>

'Do not minify', 1 => 'Minify using default minifier');?>

This option will add a random value of query string (eq. merged_style.css?rand=43562). This is useful when we need the fresh content of the css file that maybe ever cached by the browser.

'Do not merge', 1 => 'Merge and place it on the header', 2 => 'Merge and place it on the footer' );?>

'Do not minify', 1 => 'Minify using default minifier', 2 => 'Minify using default minifier + YUI Compressor' ); $disabled = $warn = ''; if (!function_exists('exec')) { $warn = "PHP exec() function is disabled, so, we don't able to use YUI Compressor"; $disabled = ' disabled="disabled"'; } else { if(!shell_exec('java -version 2>&1')) { $warn = "Your server doesn't have java installed, so, we don't able to use YUI Compressor"; } } ?> ' . $warn . '

'; } ?>

We don't use Closure Compiler as it's not 100% safe, tested on jQuery, read here.

options['script_query_string'] ? ' checked="checked"' : ''; ?>

This option will add a random value of query string (eq. merged_script.css?rand=43562). This is useful when we need the fresh content of the script that maybe ever cached by the browser.

'Don not process remote file', 1 => 'Always use remote file - fallback to local copy', 2 => 'Always use local copy - fallback to remote file', 3 => 'Use local copy if the file age less than' );?>
options['remote_files'] == 3 ? '' : ' style="display:none"'; ?>
> day(s) - fallback to remote file

Getting remote files will take a moment at the first run


How many second(s) request to remote files will timeout

'; } public function local_copy() { $lists = array('style', 'script'); foreach ($lists as $type) { ${'remote_' . $type} = false; if ($this->options['remote_handles'][$type]) { $html .= 'Remote ' . ucfirst($type) . 's :

    '; foreach ($this->options['remote_handles'][$type] as $handle => $val) { $url = $val['orig_url']; $ext = $type == 'style' ? '.css' : '.js'; $local_url = APHMS_PLUGIN_URL . '/remote/' . $handle . $ext; $html .= '

  1. Remote Url: ' . $val['orig_url'] . '
    Local Url: ' . $local_url . '
  2. '; } $html .= '

'; ${'remote_' . $type} = true; } } if (!$remote_style && !$remote_script) { echo 'Local copy file not found'; return; } $parse_url = parse_url($_SERVER['REQUEST_URI']); echo 'Clear All Local Copy Files Show Files'; echo ' '; } public function clear_local_copy() { $deleted = array_map('unlink', glob(APHMS_PLUGIN_PATH . APHMS_DS . 'remote/*.*')); $this->options['remote_handles']['style'] = array(); $this->options['remote_handles']['script'] = array(); update_option(APHMS_OPTION, $this->options); // Save notice if ($deleted[0]) $msg = 'Local copy file(s) have successfully been deleted.'; else $msg = 'Local copy file(s) could not be deleted.'; $this->admin_notices->add_notice($msg, 'success', true, true); wp_redirect( remove_query_arg('_wpnonce') ); exit; } public function submit_validation($inputs) { foreach ($this->add_options as $key => $val) { if (!key_exists($key, $inputs)) { if (key_exists($key, $this->options)) $inputs[$key] = $this->options[$key]; else $inputs[$key] = $val; } } // echo '
'; print_r($inputs); die;
		return $inputs;
	}
	
	public function cache_age()
	{ ?>
	
		 day(s)
		

Fill 0 to force the plugin to generate new merged file

While using the cache, the plugin will always check what style and script files are merged into the cache file, if those files are meet all of the files needed by the current page, then cached version is used, otherwise, the plugin will generate new merged file.

'; foreach ($lists as $key => $list) { $selected = $key == $this->options['run_on_404'] ? ' selected="selected"' : ''; echo ''; } ?>

If chosing yes, then MAKE SURE that there is NO broken link of assets (css, js, fonts). In broken links, WordPress will redirect to 404 page in the background, so this plugin will also run in the background and break the merged CSS and JS.

options['manage_scripts'] ? ' checked="checked"' : ''; ?>

While opening a page, the plugin will automatically detect and merge javascript files that are loaded, but on certain conditions, not all of those scripts can be detected (typically scripts loaded very late in the wp_footer such as: akismet-form).

You can find these files through the "APH Merge Scripts" menu located on the admin bar on each page, this menu appears when you open a page, from that menu, you can add those kind of files to manually combine with others.

When this option is activated and the admin bar is displayed, the plugin will stop merging scripts

options['excluded_handles']) == 1 && in_array('merged-script', $this->options['excluded_handles'])) { echo 'Excluded handle not found'; } else { echo '

The following script handle(s) are excluded from merging:

    '; foreach ($this->options['excluded_handles'] as $handle) { if ($handle == 'merged-script') continue; echo '
  1. ' . $handle . '
  2. '; } echo '
You can include those handle(s) to be merged with others through Admin Bar on the page where the script is loaded. Don\'t forget to activate the option: "Show Manage Scripts Menu on the Admin Bar"

'; } } public function clear_cache_options() { $file_style = APHMS_PLUGIN_PATH . APHMS_DS . 'merged' . APHMS_DS . 'merged-style-' . $this->options['curr_handles']['style']['time'] . '.css'; $file_script = APHMS_PLUGIN_PATH . APHMS_DS . 'merged' . APHMS_DS . 'merged-script-' . $this->options['curr_handles']['script']['time'] . '.js'; $file_style_exists = file_exists($file_style); $file_script_exists = file_exists($file_script); if ($file_style_exists || $file_script_exists) { $site_url = site_url(); $parse_url = parse_url($_SERVER['REQUEST_URI']); echo 'Clear All Cache
'; $lists = array('style', 'script'); foreach ($lists as $type) { if (${'file_' . $type . '_exists'}) { $file_merged_url = APHMS_PLUGIN_URL . '/merged/merged-' . $type . '-' . $this->options['curr_handles'][$type]['time'] . '.js'; $file_merged_handles = APHMS_PLUGIN_PATH . APHMS_DS . 'merged' . APHMS_DS . $type . '-handles.txt'; $show_handle = file_exists($file_merged_handles) ? 'Show Handles' : '-'; echo '

' . ucfirst($type) . ' Cache:


File: ' . $file_merged_url . ' ('.round(filesize(${'file_' . $type})/1024) . ' KB )
Handles: ' . $show_handle . '

'; if (file_exists($file_merged_handles)) { $exp = explode (PHP_EOL, file_get_contents($file_merged_handles)); echo '
    '; foreach ($exp as $line) { if (trim($line) == '') continue; $split = explode(':', $line); $handle = $split[0]; unset($split[0]); $url = trim(join($split, ':')); $url = ltrim($url, '/'); $site_url = rtrim(site_url(),'/'); $domain = preg_replace('/https?:\/\//i', '', $site_url); /* SITE URL with or without http; */ if (strpos($url, $domain) !== false) { //rel path with site url without http if (strpos($url, 'http') === false) { $domain_regex = str_replace('/', '\/', $domain); // FOR regex error $url = $site_url . preg_replace('/.*' . $domain_regex . '/i', '', $url); } } // Rel path or remote else { //rel path if (strpos($url, 'http') === false) { $url = $site_url . '/' . $url; } } echo '
  1. ' . $handle . ': ' . $url . '
  2. '; } echo '
'; } echo '

'; } } echo '
'; } else { echo 'Cache file not found'; } } public function delete_cache() { $deleted = array_map('unlink', glob(APHMS_PLUGIN_PATH . APHMS_DS . 'merged/*.*')); // Save notice if ($deleted[0]) $msg = 'Cache file(s) have successfully been deleted.'; else $msg = 'Cache file(s) could not be deleted.'; $this->admin_notices->add_notice($msg, 'success', true, true); wp_redirect( remove_query_arg('_wpnonce') ); exit; } } ?>