Changeset 1910167
- Timestamp:
- 07/17/2018 06:52:37 AM (8 years ago)
- Location:
- dexecure
- Files:
-
- 6 edited
- 1 copied
-
tags/1.1 (copied) (copied from dexecure/trunk)
-
tags/1.1/cdn-loader.php (modified) (1 diff)
-
tags/1.1/readme.txt (modified) (1 diff)
-
tags/1.1/src/rewriter.php (modified) (1 diff)
-
trunk/cdn-loader.php (modified) (1 diff)
-
trunk/readme.txt (modified) (1 diff)
-
trunk/src/rewriter.php (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
dexecure/tags/1.1/cdn-loader.php
r1791690 r1910167 24 24 define("DEX_CDN_URL", "dex_cdn_url"); 25 25 if( ! defined( 'ABSPATH' ) ) { 26 exit;26 exit; 27 27 } 28 29 require_once __DIR__ . '/src/merge-minify-refresh.php';30 $mergeminifyrefresh = new DexecureMergeMinifyRefresh();31 28 32 29 if(!defined('DEX_MMR_CACHE_DIR')) 33 30 define('DEX_MMR_CACHE_DIR', WP_CONTENT_DIR.'/dexecure-merge-cache'); 34 31 35 function dexecure_add_menu_options() { 36 add_options_page( 'Dexecure', 'Dexecure', 'manage_options', 'dexecure', 'dexecure_output_page_content' ); 32 require_once(dirname(__FILE__) . '/src/rewriter.php'); 33 34 global $url_rewriter; 35 $url_rewriter = new Dex_Rewrite(); 36 37 if (!is_admin()) 38 { 39 add_action( 'get_header', array($url_rewriter, 'pre_content' ), PHP_INT_MAX); 40 add_action( 'wp_footer', array($url_rewriter, 'post_content' ), PHP_INT_MAX); 37 41 } 38 42 39 function dexecure_validate_domain( $url ) { 40 if(preg_match( '@^((https?:)?\/\/)?[a-z0-9-]+(\.[a-z0-9-]+)*\/?$@i', $url )) 41 return true; 42 else 43 return false; 44 } 43 /* Options */ 44 register_activation_hook ( __FILE__, array($url_rewriter , 'activate') ); 45 register_deactivation_hook ( __FILE__, array($url_rewriter , 'deactivation') ); 45 46 46 function dexecure_validate_cdn ( $url ) { 47 if(preg_match('@^(https?:\/\/)?d[a-z0-9]+\.cloudfront\.net\/?$@i', $url)) 48 return true; 49 else 50 return false; 51 } 47 /* Admin menu */ 48 add_action( 'admin_menu', array($url_rewriter,'dexecure_add_menu_options' )); 49 add_action( 'admin_notices', array($url_rewriter,'addNotices' )); 50 add_action ( 'admin_init' , array($url_rewriter , 'init' )); 51 //add_action ( 'admin_init' , array($url_rewriter , 'additionallCSS' )); 52 52 53 function dexecure_output_page_content() { 54 if (!current_user_can('manage_options')) { 55 wp_die( __('You do not have sufficient permissions to access this page.') ); 56 } 57 $hidden_field_name = 'submit_hidden'; 58 $hidden_field_name2 = 'submit_hidden2'; 59 $data_field_name = 'cdn_url'; 60 $opt_val = get_option( DEX_CDN_URL ); 61 if( array_key_exists('dexecure-save-nonce', $_POST) && wp_verify_nonce( $_POST['dexecure-save-nonce'], 'save-dexecure-settings' ) && isset($_POST[ $hidden_field_name ]) && $_POST[ $hidden_field_name ] == 'Y' ) { 62 $opt_val = esc_url_raw(sanitize_text_field($_POST[ $data_field_name ])); 63 $opt_val = dexecure_validate_cdn($opt_val) ? $opt_val : ""; 64 update_option( DEX_CDN_URL, $opt_val ); 65 update_option('mmr-nomergecss', isset($_POST['mmr-nomergecss']) ? 1 : 0); 66 update_option('mmr-nomergejs', isset($_POST['mmr-nomergejs']) ? 1 : 0); 67 $doms = array(); 68 $cdns = array(); 53 // add_filter( 'script_loader_src', array($url_rewriter,'dex_remove_version'), 15, 1 ); 54 // add_filter( 'style_loader_src', array($url_rewriter,'dex_remove_version'), 15, 1 ); 69 55 70 for($i = 1; $i <= 5 ; $i++) {71 if(!empty($_POST['domain'.$i]) && !empty($_POST['cdn'.$i])) {72 $dom_to_store = esc_url_raw(sanitize_text_field($_POST['domain'.$i]));73 $cdn_to_store = esc_url_raw(sanitize_text_field($_POST['cdn'.$i]));74 if( dexecure_validate_domain($dom_to_store) && dexecure_validate_cdn($cdn_to_store) ) {75 array_push($doms, $dom_to_store);76 array_push($cdns, $cdn_to_store);77 }78 }79 }80 update_option('dexListOfDomains', $doms);81 update_option('dexListOfCDNs', $cdns);82 update_option('DEX_EXCLUDES', sanitize_text_field($_POST['exclude-dirs']));83 ?>84 <div class = "updated">85 <p>86 <strong>87 Settings saved.88 </strong>89 </p>90 </div>91 <?php92 }93 if( array_key_exists('dexecure-merge-nonce', $_POST) && wp_verify_nonce( $_POST['dexecure-merge-nonce'], 'dexecure-purge-merge-cache' ) && isset($_POST[ $hidden_field_name2 ]) && $_POST[ $hidden_field_name2 ] == 'Y' ) {94 $dir = DEX_MMR_CACHE_DIR;95 if(is_dir($dir)) {96 foreach(glob($dir.'/{,.}*', GLOB_BRACE) as $file) {97 if(basename($file) != '.' && basename($file) != '..') {98 if(is_dir($file)) $this->rrmdir($file); else unlink($file);99 }100 }101 rmdir($dir);102 }103 }104 echo '<div class="wrap">';105 echo "<h2>" . 'Menu' . "</h2>";106 ?>107 <form name = "form1" method = "post" action = "">108 <input type = "hidden" name = "<?php echo esc_attr($hidden_field_name); ?>" value = "Y">109 <p>110 <h4>To serve your site assets from Dexecure:</h4>111 Dexecure CDN:112 <input type = "text" name = "<?php echo esc_attr($data_field_name); ?>" value="<?php echo esc_attr($opt_val); ?>" size = "40" placeholder = "https://xyz.cloudfront.net" pattern="^([hH][tT][tT][pP][sS]?:\/\/)?[dD][a-zA-Z0-9]+\.[cC][lL][oO][uU][dD][fF][rR][oO][nN][tT]\.[nN][eE][tT]\/?$">113 </p>114 <p>Exclusions:<br><small>A comma separated list. eg: wp-content/plugins/unsafe1/,wp-content/plugins/unsafe2/file.js</small></p><textarea name="exclude-dirs" rows="4" cols="50"><?php echo esc_attr(get_option('DEX_EXCLUDES')); ?></textarea>115 <h4>Additional domains to replace:</h4>116 <?php117 $doms = get_option('dexListOfDomains');118 $cdns = get_option('dexListOfCDNs');119 120 for($i = 0; $i < 5; $i++){121 $dom_to_print = "";122 $cdn_to_print = "";123 if(array_key_exists($i, $doms) && array_key_exists($i, $cdns)) {124 $dom_to_print = $doms[$i];125 $cdn_to_print = $cdns[$i];126 }127 echo 'Domain: <input type="text" name="domain'. esc_attr($i+1) .'" value="'. esc_attr($dom_to_print) .'" size="30">';128 echo 'CDN: <input type="text" name="cdn'. esc_attr($i+1) .'" value="'. esc_attr($cdn_to_print) .'" size="30" pattern="^([hH][tT][tT][pP][sS]?:\/\/)?[dD][a-zA-Z0-9]+\.[cC][lL][oO][uU][dD][fF][rR][oO][nN][tT]\.[nN][eE][tT]\/?$">';129 echo '<br>';130 }131 ?>132 <?php133 echo '<p><label><input type="checkbox" name="mmr-nomergecss" value="1" '.checked( 1 == get_option('mmr-nomergecss') , true, false).'/> Don\'t Merge CSS</label><br>';134 echo '<label><input type="checkbox" name="mmr-nomergejs" value="1" '.checked( 1 == get_option('mmr-nomergejs') , true, false).'/> Don\'t Merge JS</label></p>';135 ?>136 <p class = "submit">137 <input type = "submit" name = "Submit" class = "button-primary" value = "Save Changes" />138 </p>139 <?php wp_nonce_field('save-dexecure-settings', 'dexecure-save-nonce') ?>140 </form>141 <form name="form2" method="post" action="">142 <p>When a CSS or JS file is modified, merged files are re-processed automatically. However, when a dependancy changes these files may become stale.</p>143 144 <div>145 <input type = "hidden" name = "<?php echo $hidden_field_name2; ?>" value = "Y">146 <input type = "submit" name = "purge-submit" class="button-secondary" value = "Purge Merged Files" />147 <?php wp_nonce_field('dexecure-purge-merge-cache', 'dexecure-merge-nonce') ?>148 </form>149 </div>150 <?php151 }152 add_action( 'admin_menu', 'dexecure_add_menu_options' );153 154 add_action('template_redirect', 'dexecure_handle_rewrite');155 156 function dexecure_handle_rewrite() {157 158 // Don't run if SCRIPT_DEBUG is set to true159 if( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) {160 return;161 }162 163 if(get_option(DEX_CDN_URL) == "")164 return;165 166 $domains = array(get_option('home'));167 $cdns = array(get_option(DEX_CDN_URL));168 169 if(get_option('dexListOfDomains') != '' && get_option('dexListOfCDNs') != ''){170 $domains = array_merge($domains, get_option('dexListOfDomains'));171 $cdns = array_merge($cdns, get_option('dexListOfCDNs'));172 }173 require_once __DIR__ . '/src/rewriter.php';174 $rewriter = new Dex_Rewriter($domains, $cdns);175 ob_start(array(&$rewriter, 'filter_html'));176 } -
dexecure/tags/1.1/readme.txt
r1791692 r1910167 2 2 Tags: Advanced website optimization 3 3 Requires at least: 3.6.1 4 Tested up to: 4. 8.45 Stable tag: 1. 04 Tested up to: 4.9.7 5 Stable tag: 1.1 6 6 License: GPLv2 or later 7 7 License URI: https://www.gnu.org/licenses/gpl-2.0.html -
dexecure/tags/1.1/src/rewriter.php
r1791690 r1910167 20 20 */ 21 21 22 class Dex_Rewrite r22 class Dex_Rewrite 23 23 { 24 var $site_url = null; 25 var $cdn_url = null; 26 var $domains = array(); 27 var $cdns = array(); 28 29 function __construct(array $domains, array $cdns) { 30 31 foreach($domains as $dom) { 32 array_push($this->domains, wp_parse_url($dom, PHP_URL_HOST)); 33 } 34 35 foreach($cdns as $cdn) { 36 array_push($this->cdns, wp_parse_url($cdn, PHP_URL_HOST)); 37 } 38 39 $this->site_url = get_option('home'); 40 $this->cdn_url = get_option(DEX_CDN_URL); // obsolete? 41 add_filter( 'script_loader_src', array( $this, 'rewrite' ), 99, 1 ); 42 add_filter( 'style_loader_src', array( $this, 'rewrite' ), 99, 1 ); 43 } 44 45 private function is_url_relative($url) { 46 if (substr($url, 0, 5) == "data:") 47 return false; 48 if (strlen($url) == 0) 49 return false; 50 if ((substr( $url, 0, 1 ) === "/") and (substr( $url, 1, 1 ) !== "/")) { 51 return true; 52 } else if ((substr($url, 0, 2) !== "//") && (substr($url, 0, 4) !== "http")){ 53 return true; 54 } else { 55 return false; 56 } 57 } 58 59 private function convert_relative_to_absolute_url($url) { 60 $slash = substr($url, 0, 1) !== "/" ? "/" : ""; 61 $url = $this->site_url . $slash . $url; 62 return $url; 63 } 64 65 public function rewrite_srcset( $srcset ) { 66 $srcset = str_replace( $this->domains, $this->cdns, $srcset ); 67 return $srcset; 68 } 69 70 public function rewrite( $url ) { 71 if ($this->is_url_relative( $url )) { 72 $url = $this->convert_relative_to_absolute_url($url); 73 } 74 $parsed = wp_parse_url( $url ); 75 $key = 0; 76 $replace = ''; 77 $search = ''; 78 79 if(isset($parsed['host']) && in_array($parsed['host'], $this->domains)) { 80 81 $key = array_search($parsed['host'], $this->domains); 82 //all this for a case where domain name exists somewhere in the url (path or filename) 83 if ( isset( $parsed['scheme'] ) ) { 84 $replace .= $parsed['scheme'] . '://'; 85 $search .= $parsed['scheme'] . '://'; 86 } elseif ( '/' === $url[0] ) { 87 $replace .= '//'; 88 $search .= '//'; 89 } 90 91 if ( isset( $parsed['user'] ) ) { 92 $replace .= $parsed['user']; 93 $search .= $parsed['user']; 94 } 95 96 if ( isset( $parsed['pass'] ) ) { 97 $replace .= ':' . $parsed['pass']; 98 $search .= ':' . $parsed['pass']; 99 } 100 101 if ( isset( $parsed['user'] ) || isset( $parsed['pass'] ) ) { 102 $replace .= '@'; 103 $search .= '@'; 104 } 105 106 if ( isset( $parsed['host'] ) ) { 107 $replace .= $this->cdns[$key]; // replace with cdn 108 $search .= $parsed['host']; 109 } 110 111 if ( isset( $parsed['port'] ) ) { 112 $replace .= ':' . $parsed['port']; 113 $search .= ':' . $parsed['port']; 114 } 115 116 //parsed could also containg query and fragment 117 $url = str_replace($search, $replace, $url); 118 } 119 return $url; 120 } 121 122 public function parse_assets_from_html( $content ) { 123 $assets = array(); 124 $srcsets = array(); 125 126 preg_match_all( '@(<\s*img[^>]*?\s+?srcset\s*\=\s*["|\'](?P<img_srcset_url>[^"\'<>]+?)["|\'].*?>)@i', $content, $srcsets ); 127 preg_match_all( '@(<\s*img[^>]*?\s+?src\s*\=\s*["|\'](?P<img_url>[^\s]+?)["|\'].*?>)|(?:background\-image\s*\:\s*url\s*\(\s*["\']?\s*(?P<bg_img_url>[^\s]+?)\s*["\']?\s*\)\s*)|(<\s*script\s+?[^<>]*?src\s*\=\s*["|\'](?P<js_url>[^"\'<>]+)["|\'][^<>]*>)|(<\s*link\s+[^<>]*?rel\s*\=\s*["|\']stylesheet["|\'][^<>]*?href\s*=\s*["|\'](?<css_url1>[^"\'<>]+)["|\'][^<>]*>)|(<\s*link\s+[^<>]*?href\s*=\s*["|\'](?<css_url2>[^"\'<>]+)["|\'][^<>]*?rel\s*\=\s*["|\']stylesheet["|\'][^<>]*>)|(background\s*:\s*url\(\s*["\']?\s*(?P<style_background_url>\S*?)\s*["\']?\s*\);?)|(<\s*video[^>]+poster\s*=\s*["|\'](?P<video_poster_url>[^<>\\"]+)["|\'][^>]*>)|(<\s*div[^>]*?\s+?bgimage\s*\=\s*["|\'](?P<div_bgimage_url>[^"\'<>]+?)["|\'].*?>)@i', $content, $assets ); 128 129 $assets = array_merge($srcsets, $assets); 130 foreach ( $assets as $key => $unused ) { 131 if ( is_int( $key ) && $key >= 0 ) 132 unset( $assets[$key] ); 133 } 134 return $assets; 135 } 136 137 public function filter_html($content) { 138 $new_content = $content; 139 $assets = $this->parse_assets_from_html( $content ); 140 141 //workaround for srcset 142 if(isset($assets['img_srcset_url'])) { 143 foreach($assets['img_srcset_url'] as $pattern) { 144 if(strlen($pattern) === 0) 145 continue; 146 if($this->excluded_directory($pattern)) 147 continue; 148 $pattern_with_cdn_src = $this->rewrite_srcset($pattern); 149 $new_content = str_replace($pattern, $pattern_with_cdn_src, $new_content); 150 } 151 unset($assets['img_srcset_url']); 152 } 153 154 if ( ! empty( $assets ) ) { 155 foreach($assets as $type) { 156 foreach($type as $pattern) { 157 if(strlen($pattern) === 0) 158 continue; 159 if($this->excluded_directory($pattern)) 160 continue; 161 $pattern_with_cdn_src = $this->rewrite($pattern); 162 $new_content = str_replace($pattern, $pattern_with_cdn_src, $new_content); 163 } 164 } 165 } 166 return $new_content; 167 } 168 169 public function excluded_directory($url) { 170 $excludes = explode(",", get_option('DEX_EXCLUDES')); 171 foreach($excludes as $dir) { 172 if(!empty($dir)) { 173 if(strpos($url, $dir)) 174 return true; 175 } 176 } 177 return false; 178 } 179 } 24 var $host; 25 var $cdn; 26 var $options = array(); //dex_options 27 var $excludes = array(); // excludes 28 29 30 function __construct() 31 { 32 $this -> host = get_option('home'); 33 $opt = get_option( 'dex_cdn_options' ); 34 $this -> cdn = $opt['cdn_url']; 35 $exclude = get_option( 'dex_cdn_options' ); 36 $this-> excludes = $exclude['excludes']; 37 } 38 39 /** 40 * Function to activate the plugin 41 */ 42 function activate() { 43 $pluginOptions = get_option('dex_cdn_options'); 44 45 if ( !$pluginOptions ) { 46 add_option ( 'dex_cdn_options' , $this -> options ); 47 } 48 } 49 50 /** 51 * Erase options data when deactivate 52 */ 53 function deactivation() { 54 delete_option ( 'dex_cdn_options' ); 55 unregister_setting ( 'dex_cdn_settings' , 'dex_cdn_options' ); 56 } 57 58 /** 59 * Create the admin page options 60 */ 61 function dexecure_add_menu_options() { 62 add_options_page('Dexecure', 'Dexecure', 'manage_options', 'dexecure', array($this,'dexecure_output_page_content')); 63 } 64 65 /** 66 * Set the errors options 67 */ 68 function addNotices() { 69 settings_errors('dex_cdn_errors'); 70 } 71 72 /** 73 * Define the set of options 74 */ 75 function init(){ 76 register_setting ( 'dex_cdn_settings' , 'dex_cdn_options'); 77 } 78 79 function additionallCSS(){ 80 ?> 81 <style> 82 #wpfooter { 83 position: unset!important 84 } 85 </style> 86 <?php 87 } 88 89 /** 90 * Function to clean the inputs 91 * @param array $input from the form 92 * @return array with clean inputs 93 */ 94 function sanitize($input){ 95 add_settings_error( 96 'dex_cdn_errors', 97 'dex_cdn_success', 98 'Settings saved.', 99 'updated' 100 ); 101 102 return $input; 103 } 104 105 function dexecure_validate_cdn ( $url ) { 106 $cdn = esc_url_raw(sanitize_text_field($url)); 107 if(preg_match('@^https?:\/\/d[a-z0-9]+\.cloudfront\.net\/?$@i', $cdn)) 108 if(substr($cdn, -1) == '/') 109 return substr($cdn, 0, -1); 110 else 111 return $cdn; 112 else 113 return ''; 114 } 115 116 /** 117 * Function to create the page with form to config plugin 118 */ 119 function dexecure_output_page_content(){ 120 121 if( array_key_exists('dexecure-merge-nonce', $_POST) && wp_verify_nonce( $_POST['dexecure-merge-nonce'], 'dexecure-purge-merge-cache' ) && isset($_POST[ 'submit_hidden' ]) && $_POST[ 'submit_hidden' ] == 'Y' ) { 122 $dir = DEX_MMR_CACHE_DIR; 123 if(is_dir($dir)) { 124 foreach(glob($dir.'/{,.}*', GLOB_BRACE) as $file) { 125 if(basename($file) != '.' && basename($file) != '..') { 126 if(is_dir($file)) $this->rrmdir($file); else unlink($file); 127 } 128 } 129 rmdir($dir); 130 } 131 } 132 ?> 133 <div class="wrap"> 134 <h2>Menu</h2> 135 136 <form method="post" action="options.php" id="dex_cdn_form" > 137 <?php 138 settings_fields('dex_cdn_settings'); 139 140 $this -> options = get_option('dex_cdn_options'); 141 $this->options['cdn_url'] = $this->dexecure_validate_cdn($this->options['cdn_url']); 142 $this->options['excludes'] = sanitize_text_field($this->options['excludes']); 143 update_option('dex_cdn_options', $this->options); 144 145 146 if (!is_array($this->options)) 147 $this -> options = array(); 148 $opt = get_option( 'dex_cdn_options' ); 149 if(!empty($opt['excludes'])){ $opt_excl = $opt['excludes']; } else { $opt_excl = ''; } 150 151 if(!empty($opt['cdn_url'])){ $opt_val = $opt['cdn_url']; } else { $opt_val = ''; } 152 153 /* 154 if (!preg_match("~^(?:f|ht)tps?://~i", $opt_val)) { 155 $opt_val = "http://" . $opt_val; 156 }*/ 157 158 ?> 159 160 <div id="main" class="main"> 161 162 <div> 163 <h4>To serve your site assets from Dexecure:</h4> 164 Dexecure CDN: 165 <input type = "text" name = "dex_cdn_options[cdn_url]" id="cdn_url" value="<?php echo esc_attr($opt_val); ?>" size = "40" placeholder = "https://xyz.cloudfront.net" pattern="^([hH][tT][tT][pP][sS]?:\/\/)?[dD][a-zA-Z0-9]+\.[cC][lL][oO][uU][dD][fF][rR][oO][nN][tT]\.[nN][eE][tT]\/?$"> 166 </div> 167 <small>Add <b>http://</b> </small> 168 169 <h4>Exclusions:</h4> 170 <small>A comma separated list. eg: wp-content/plugins/unsafe1/,wp-content/plugins/unsafe2/file.js</small> 171 172 <div><label for="excludes"> 173 <textarea cols="50" rows="4" name="dex_cdn_options[excludes]" id="excludes"/><?php echo esc_attr($opt_excl); ?></textarea> 174 </label> 175 </div> 176 177 178 <h4>Choose which content will be retrieved from CDN:</h4> 179 180 181 <div class="chkbox"><label for="images"> 182 <input type="checkbox" id="images" name="dex_cdn_options[]" value="images"<?php if (in_array('images', $this->options)) echo ' checked="checked"' ?> />Images</label> 183 </div> 184 <div class="chkbox"><label for="contentcs"> 185 <input type="checkbox" id="contentcs" name="dex_cdn_options[]" value="contentcs"<?php if (in_array('contentcs', $this->options)) echo ' checked="checked"' ?> />CSS files</label> 186 </div> 187 188 <div class="chkbox"><label for="content"> 189 <input type="checkbox" id="content" name="dex_cdn_options[]" value="content"<?php if (in_array('content', $this->options)) echo ' checked="checked"' ?> />JS files</label> 190 </div> 191 192 193 194 </div> 195 196 <div class="submit"><input type="submit" name="submit" id="submit" class="button-primary" value="Save Changes" /></div> 197 </div> 198 </form> 199 200 <form name="form2" method="post" action=""> 201 <h4>When a CSS or JS file is modified, merged files are re-processed automatically. However, when a dependency changes these files may become stale.</h4> 202 203 <div> 204 <input type = "hidden" name = "submit_hidden" value = "Y"> 205 <input type = "submit" name = "purge-submit" class="button-secondary" value = "Purge Merged Files" /> 206 <?php wp_nonce_field('dexecure-purge-merge-cache', 'dexecure-merge-nonce') ?> 207 </form> 208 </div> 209 <?php 210 } 211 212 /** 213 * Start the buffer to get the content 214 */ 215 function pre_content() 216 { 217 ob_start(); 218 219 $this->merge_all_scripts(); 220 $this->merge_all_styles(); 221 222 } 223 224 /** 225 * Get the content from the buffer and parse it 226 */ 227 function post_content() 228 { 229 $html = ob_get_contents(); 230 ob_end_clean(); 231 232 echo $this->parse($html); 233 234 } 235 236 /** 237 * @param string $html 238 * Parse the original host into CDN host 239 */ 240 function parse($html) 241 { 242 243 $regex = array(); 244 245 $this -> options = get_option('dex_cdn_options'); 246 247 if ( $this -> cdn != $this -> host && is_array($this->options) && !empty($this->options)){ 248 //Images 249 if (in_array('images', $this->options)) 250 $regex['img'] = '/' . preg_quote($this->host , '/') . '\/(((?!gallery\.php)(?![\w-]+\/gallery-image))\S+\.(png|jpg|jpeg|gif|ico))/i'; 251 252 //CSS 253 if (in_array('contentcs', $this->options)) 254 $regex['contentcs'] = '/' . preg_quote($this->host , '/') . '\/(\S+\.(css))/i'; 255 256 //JS 257 if (in_array('content', $this->options)) 258 $regex['content'] = '/' . preg_quote($this->host , '/') . '\/(\S+\.(js))/i'; 259 260 //Exclusions 261 if(array_key_exists('excludes', $this->options) && !empty($this-> excludes)){ 262 $excludes = array_map('trim', explode(',', $this-> excludes)); 263 264 for( $i=0 ; $i<count($excludes) ; $i++ ){ 265 266 if(!empty( $excludes)){ 267 268 $regex1['excludes'] = $this->host.'/'.$excludes[$i]; 269 270 //print_r($regex1); 271 272 $html = str_replace( $regex1, $this->host.'\\'.$excludes[$i] , $html); 273 } 274 } 275 } 276 277 if(!empty($regex)) 278 $html = preg_replace( $regex , $this->cdn.'/$1' , $html); 279 280 281 } 282 return $html; 283 } 284 285 /** 286 * Remove query string from CSS/ JSS 287 */ 288 function dex_remove_version( $src ){ 289 $parts = explode( '?ver', $src ); 290 return $parts[0]; 291 } 292 293 /** 294 * Parse the original JS host into CDN host 295 */ 296 function merge_all_scripts() { 297 298 global $wp_scripts; 299 300 $this -> options = get_option('dex_cdn_options'); 301 302 if (in_array('comjsfile', $this->options)) { 303 304 $wp_scripts->all_deps($wp_scripts->queue); 305 306 $merged_file_location = get_stylesheet_directory() . DIRECTORY_SEPARATOR . 'dex-merged-script.js'; 307 308 $merged_script = ''; 309 310 // Loop javascript files and save to $merged_script variable 311 foreach( $wp_scripts->to_do as $handle) 312 { 313 314 $src = strtok($wp_scripts->registered[$handle]->src, '?'); 315 316 317 if (strpos($src, 'http') !== false) 318 { 319 320 $site_url = site_url(); 321 322 if (strpos($src, $site_url) !== false) 323 $js_file_path = str_replace($site_url, '', $src); 324 else 325 $js_file_path = $src; 326 327 $js_file_path = ltrim($js_file_path, '/'); 328 } 329 else 330 { 331 $js_file_path = ltrim($src, '/'); 332 } 333 334 if (file_exists($js_file_path)) 335 { 336 $localize = ''; 337 if (@key_exists('data', $wp_scripts->registered[$handle]->extra)) { 338 $localize = $obj->extra['data'] . ';'; 339 } 340 $merged_script .= $localize . file_get_contents($js_file_path) . ';'; 341 } 342 } 343 344 file_put_contents ( $merged_file_location , $merged_script); 345 346 wp_enqueue_script('merged-script', get_stylesheet_directory_uri() . '/dex-merged-script.js'); 347 348 foreach( $wp_scripts->to_do as $handle ) 349 { 350 wp_deregister_script($handle); 351 } 352 353 }// end if in_array 354 355 } 356 357 /** 358 * Parse the original CSS host into CDN host 359 */ 360 361 function merge_all_styles(){ 362 363 $this -> options = get_option('dex_cdn_options'); 364 365 //print_r($this -> options); 366 367 if (in_array('comcssfile', $this->options)) { 368 369 wp_styles(); 370 371 global $wp_styles; 372 373 $wp_styles->all_deps($wp_styles->queue); 374 375 $handles = $wp_styles->to_do; 376 377 $css_code = ''; 378 379 $merged_file_location = get_stylesheet_directory() . DIRECTORY_SEPARATOR . 'dex-merged-style.css'; 380 381 foreach ($handles as $handle) 382 { 383 384 $src = strtok($wp_styles->registered[$handle]->src, '?'); 385 386 if (strpos($src, 'http') !== false) 387 { 388 $site_url = site_url(); 389 390 if (strpos($src, $site_url) !== false) 391 $css_file_path = str_replace($site_url, '', $src); 392 else 393 $css_file_path = $src; 394 395 $css_file_path = ltrim($css_file_path, '/'); 396 } 397 else 398 { 399 $css_file_path = ltrim($src, '/'); 400 } 401 402 if (file_exists($css_file_path)) { 403 $css_code .= file_get_contents($css_file_path); 404 } 405 } 406 407 file_put_contents ( $merged_file_location , $css_code); 408 409 wp_enqueue_style('merged-style', get_stylesheet_directory_uri() . '/dex-merged-style.css'); 410 411 foreach ($handles as $handle) 412 { 413 wp_deregister_style($handle); 414 } 415 }//end if in_array 416 } 417 418 }// End Class -
dexecure/trunk/cdn-loader.php
r1791690 r1910167 24 24 define("DEX_CDN_URL", "dex_cdn_url"); 25 25 if( ! defined( 'ABSPATH' ) ) { 26 exit;26 exit; 27 27 } 28 29 require_once __DIR__ . '/src/merge-minify-refresh.php';30 $mergeminifyrefresh = new DexecureMergeMinifyRefresh();31 28 32 29 if(!defined('DEX_MMR_CACHE_DIR')) 33 30 define('DEX_MMR_CACHE_DIR', WP_CONTENT_DIR.'/dexecure-merge-cache'); 34 31 35 function dexecure_add_menu_options() { 36 add_options_page( 'Dexecure', 'Dexecure', 'manage_options', 'dexecure', 'dexecure_output_page_content' ); 32 require_once(dirname(__FILE__) . '/src/rewriter.php'); 33 34 global $url_rewriter; 35 $url_rewriter = new Dex_Rewrite(); 36 37 if (!is_admin()) 38 { 39 add_action( 'get_header', array($url_rewriter, 'pre_content' ), PHP_INT_MAX); 40 add_action( 'wp_footer', array($url_rewriter, 'post_content' ), PHP_INT_MAX); 37 41 } 38 42 39 function dexecure_validate_domain( $url ) { 40 if(preg_match( '@^((https?:)?\/\/)?[a-z0-9-]+(\.[a-z0-9-]+)*\/?$@i', $url )) 41 return true; 42 else 43 return false; 44 } 43 /* Options */ 44 register_activation_hook ( __FILE__, array($url_rewriter , 'activate') ); 45 register_deactivation_hook ( __FILE__, array($url_rewriter , 'deactivation') ); 45 46 46 function dexecure_validate_cdn ( $url ) { 47 if(preg_match('@^(https?:\/\/)?d[a-z0-9]+\.cloudfront\.net\/?$@i', $url)) 48 return true; 49 else 50 return false; 51 } 47 /* Admin menu */ 48 add_action( 'admin_menu', array($url_rewriter,'dexecure_add_menu_options' )); 49 add_action( 'admin_notices', array($url_rewriter,'addNotices' )); 50 add_action ( 'admin_init' , array($url_rewriter , 'init' )); 51 //add_action ( 'admin_init' , array($url_rewriter , 'additionallCSS' )); 52 52 53 function dexecure_output_page_content() { 54 if (!current_user_can('manage_options')) { 55 wp_die( __('You do not have sufficient permissions to access this page.') ); 56 } 57 $hidden_field_name = 'submit_hidden'; 58 $hidden_field_name2 = 'submit_hidden2'; 59 $data_field_name = 'cdn_url'; 60 $opt_val = get_option( DEX_CDN_URL ); 61 if( array_key_exists('dexecure-save-nonce', $_POST) && wp_verify_nonce( $_POST['dexecure-save-nonce'], 'save-dexecure-settings' ) && isset($_POST[ $hidden_field_name ]) && $_POST[ $hidden_field_name ] == 'Y' ) { 62 $opt_val = esc_url_raw(sanitize_text_field($_POST[ $data_field_name ])); 63 $opt_val = dexecure_validate_cdn($opt_val) ? $opt_val : ""; 64 update_option( DEX_CDN_URL, $opt_val ); 65 update_option('mmr-nomergecss', isset($_POST['mmr-nomergecss']) ? 1 : 0); 66 update_option('mmr-nomergejs', isset($_POST['mmr-nomergejs']) ? 1 : 0); 67 $doms = array(); 68 $cdns = array(); 53 // add_filter( 'script_loader_src', array($url_rewriter,'dex_remove_version'), 15, 1 ); 54 // add_filter( 'style_loader_src', array($url_rewriter,'dex_remove_version'), 15, 1 ); 69 55 70 for($i = 1; $i <= 5 ; $i++) {71 if(!empty($_POST['domain'.$i]) && !empty($_POST['cdn'.$i])) {72 $dom_to_store = esc_url_raw(sanitize_text_field($_POST['domain'.$i]));73 $cdn_to_store = esc_url_raw(sanitize_text_field($_POST['cdn'.$i]));74 if( dexecure_validate_domain($dom_to_store) && dexecure_validate_cdn($cdn_to_store) ) {75 array_push($doms, $dom_to_store);76 array_push($cdns, $cdn_to_store);77 }78 }79 }80 update_option('dexListOfDomains', $doms);81 update_option('dexListOfCDNs', $cdns);82 update_option('DEX_EXCLUDES', sanitize_text_field($_POST['exclude-dirs']));83 ?>84 <div class = "updated">85 <p>86 <strong>87 Settings saved.88 </strong>89 </p>90 </div>91 <?php92 }93 if( array_key_exists('dexecure-merge-nonce', $_POST) && wp_verify_nonce( $_POST['dexecure-merge-nonce'], 'dexecure-purge-merge-cache' ) && isset($_POST[ $hidden_field_name2 ]) && $_POST[ $hidden_field_name2 ] == 'Y' ) {94 $dir = DEX_MMR_CACHE_DIR;95 if(is_dir($dir)) {96 foreach(glob($dir.'/{,.}*', GLOB_BRACE) as $file) {97 if(basename($file) != '.' && basename($file) != '..') {98 if(is_dir($file)) $this->rrmdir($file); else unlink($file);99 }100 }101 rmdir($dir);102 }103 }104 echo '<div class="wrap">';105 echo "<h2>" . 'Menu' . "</h2>";106 ?>107 <form name = "form1" method = "post" action = "">108 <input type = "hidden" name = "<?php echo esc_attr($hidden_field_name); ?>" value = "Y">109 <p>110 <h4>To serve your site assets from Dexecure:</h4>111 Dexecure CDN:112 <input type = "text" name = "<?php echo esc_attr($data_field_name); ?>" value="<?php echo esc_attr($opt_val); ?>" size = "40" placeholder = "https://xyz.cloudfront.net" pattern="^([hH][tT][tT][pP][sS]?:\/\/)?[dD][a-zA-Z0-9]+\.[cC][lL][oO][uU][dD][fF][rR][oO][nN][tT]\.[nN][eE][tT]\/?$">113 </p>114 <p>Exclusions:<br><small>A comma separated list. eg: wp-content/plugins/unsafe1/,wp-content/plugins/unsafe2/file.js</small></p><textarea name="exclude-dirs" rows="4" cols="50"><?php echo esc_attr(get_option('DEX_EXCLUDES')); ?></textarea>115 <h4>Additional domains to replace:</h4>116 <?php117 $doms = get_option('dexListOfDomains');118 $cdns = get_option('dexListOfCDNs');119 120 for($i = 0; $i < 5; $i++){121 $dom_to_print = "";122 $cdn_to_print = "";123 if(array_key_exists($i, $doms) && array_key_exists($i, $cdns)) {124 $dom_to_print = $doms[$i];125 $cdn_to_print = $cdns[$i];126 }127 echo 'Domain: <input type="text" name="domain'. esc_attr($i+1) .'" value="'. esc_attr($dom_to_print) .'" size="30">';128 echo 'CDN: <input type="text" name="cdn'. esc_attr($i+1) .'" value="'. esc_attr($cdn_to_print) .'" size="30" pattern="^([hH][tT][tT][pP][sS]?:\/\/)?[dD][a-zA-Z0-9]+\.[cC][lL][oO][uU][dD][fF][rR][oO][nN][tT]\.[nN][eE][tT]\/?$">';129 echo '<br>';130 }131 ?>132 <?php133 echo '<p><label><input type="checkbox" name="mmr-nomergecss" value="1" '.checked( 1 == get_option('mmr-nomergecss') , true, false).'/> Don\'t Merge CSS</label><br>';134 echo '<label><input type="checkbox" name="mmr-nomergejs" value="1" '.checked( 1 == get_option('mmr-nomergejs') , true, false).'/> Don\'t Merge JS</label></p>';135 ?>136 <p class = "submit">137 <input type = "submit" name = "Submit" class = "button-primary" value = "Save Changes" />138 </p>139 <?php wp_nonce_field('save-dexecure-settings', 'dexecure-save-nonce') ?>140 </form>141 <form name="form2" method="post" action="">142 <p>When a CSS or JS file is modified, merged files are re-processed automatically. However, when a dependancy changes these files may become stale.</p>143 144 <div>145 <input type = "hidden" name = "<?php echo $hidden_field_name2; ?>" value = "Y">146 <input type = "submit" name = "purge-submit" class="button-secondary" value = "Purge Merged Files" />147 <?php wp_nonce_field('dexecure-purge-merge-cache', 'dexecure-merge-nonce') ?>148 </form>149 </div>150 <?php151 }152 add_action( 'admin_menu', 'dexecure_add_menu_options' );153 154 add_action('template_redirect', 'dexecure_handle_rewrite');155 156 function dexecure_handle_rewrite() {157 158 // Don't run if SCRIPT_DEBUG is set to true159 if( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) {160 return;161 }162 163 if(get_option(DEX_CDN_URL) == "")164 return;165 166 $domains = array(get_option('home'));167 $cdns = array(get_option(DEX_CDN_URL));168 169 if(get_option('dexListOfDomains') != '' && get_option('dexListOfCDNs') != ''){170 $domains = array_merge($domains, get_option('dexListOfDomains'));171 $cdns = array_merge($cdns, get_option('dexListOfCDNs'));172 }173 require_once __DIR__ . '/src/rewriter.php';174 $rewriter = new Dex_Rewriter($domains, $cdns);175 ob_start(array(&$rewriter, 'filter_html'));176 } -
dexecure/trunk/readme.txt
r1791692 r1910167 2 2 Tags: Advanced website optimization 3 3 Requires at least: 3.6.1 4 Tested up to: 4. 8.45 Stable tag: 1. 04 Tested up to: 4.9.7 5 Stable tag: 1.1 6 6 License: GPLv2 or later 7 7 License URI: https://www.gnu.org/licenses/gpl-2.0.html -
dexecure/trunk/src/rewriter.php
r1791690 r1910167 20 20 */ 21 21 22 class Dex_Rewrite r22 class Dex_Rewrite 23 23 { 24 var $site_url = null; 25 var $cdn_url = null; 26 var $domains = array(); 27 var $cdns = array(); 28 29 function __construct(array $domains, array $cdns) { 30 31 foreach($domains as $dom) { 32 array_push($this->domains, wp_parse_url($dom, PHP_URL_HOST)); 33 } 34 35 foreach($cdns as $cdn) { 36 array_push($this->cdns, wp_parse_url($cdn, PHP_URL_HOST)); 37 } 38 39 $this->site_url = get_option('home'); 40 $this->cdn_url = get_option(DEX_CDN_URL); // obsolete? 41 add_filter( 'script_loader_src', array( $this, 'rewrite' ), 99, 1 ); 42 add_filter( 'style_loader_src', array( $this, 'rewrite' ), 99, 1 ); 43 } 44 45 private function is_url_relative($url) { 46 if (substr($url, 0, 5) == "data:") 47 return false; 48 if (strlen($url) == 0) 49 return false; 50 if ((substr( $url, 0, 1 ) === "/") and (substr( $url, 1, 1 ) !== "/")) { 51 return true; 52 } else if ((substr($url, 0, 2) !== "//") && (substr($url, 0, 4) !== "http")){ 53 return true; 54 } else { 55 return false; 56 } 57 } 58 59 private function convert_relative_to_absolute_url($url) { 60 $slash = substr($url, 0, 1) !== "/" ? "/" : ""; 61 $url = $this->site_url . $slash . $url; 62 return $url; 63 } 64 65 public function rewrite_srcset( $srcset ) { 66 $srcset = str_replace( $this->domains, $this->cdns, $srcset ); 67 return $srcset; 68 } 69 70 public function rewrite( $url ) { 71 if ($this->is_url_relative( $url )) { 72 $url = $this->convert_relative_to_absolute_url($url); 73 } 74 $parsed = wp_parse_url( $url ); 75 $key = 0; 76 $replace = ''; 77 $search = ''; 78 79 if(isset($parsed['host']) && in_array($parsed['host'], $this->domains)) { 80 81 $key = array_search($parsed['host'], $this->domains); 82 //all this for a case where domain name exists somewhere in the url (path or filename) 83 if ( isset( $parsed['scheme'] ) ) { 84 $replace .= $parsed['scheme'] . '://'; 85 $search .= $parsed['scheme'] . '://'; 86 } elseif ( '/' === $url[0] ) { 87 $replace .= '//'; 88 $search .= '//'; 89 } 90 91 if ( isset( $parsed['user'] ) ) { 92 $replace .= $parsed['user']; 93 $search .= $parsed['user']; 94 } 95 96 if ( isset( $parsed['pass'] ) ) { 97 $replace .= ':' . $parsed['pass']; 98 $search .= ':' . $parsed['pass']; 99 } 100 101 if ( isset( $parsed['user'] ) || isset( $parsed['pass'] ) ) { 102 $replace .= '@'; 103 $search .= '@'; 104 } 105 106 if ( isset( $parsed['host'] ) ) { 107 $replace .= $this->cdns[$key]; // replace with cdn 108 $search .= $parsed['host']; 109 } 110 111 if ( isset( $parsed['port'] ) ) { 112 $replace .= ':' . $parsed['port']; 113 $search .= ':' . $parsed['port']; 114 } 115 116 //parsed could also containg query and fragment 117 $url = str_replace($search, $replace, $url); 118 } 119 return $url; 120 } 121 122 public function parse_assets_from_html( $content ) { 123 $assets = array(); 124 $srcsets = array(); 125 126 preg_match_all( '@(<\s*img[^>]*?\s+?srcset\s*\=\s*["|\'](?P<img_srcset_url>[^"\'<>]+?)["|\'].*?>)@i', $content, $srcsets ); 127 preg_match_all( '@(<\s*img[^>]*?\s+?src\s*\=\s*["|\'](?P<img_url>[^\s]+?)["|\'].*?>)|(?:background\-image\s*\:\s*url\s*\(\s*["\']?\s*(?P<bg_img_url>[^\s]+?)\s*["\']?\s*\)\s*)|(<\s*script\s+?[^<>]*?src\s*\=\s*["|\'](?P<js_url>[^"\'<>]+)["|\'][^<>]*>)|(<\s*link\s+[^<>]*?rel\s*\=\s*["|\']stylesheet["|\'][^<>]*?href\s*=\s*["|\'](?<css_url1>[^"\'<>]+)["|\'][^<>]*>)|(<\s*link\s+[^<>]*?href\s*=\s*["|\'](?<css_url2>[^"\'<>]+)["|\'][^<>]*?rel\s*\=\s*["|\']stylesheet["|\'][^<>]*>)|(background\s*:\s*url\(\s*["\']?\s*(?P<style_background_url>\S*?)\s*["\']?\s*\);?)|(<\s*video[^>]+poster\s*=\s*["|\'](?P<video_poster_url>[^<>\\"]+)["|\'][^>]*>)|(<\s*div[^>]*?\s+?bgimage\s*\=\s*["|\'](?P<div_bgimage_url>[^"\'<>]+?)["|\'].*?>)@i', $content, $assets ); 128 129 $assets = array_merge($srcsets, $assets); 130 foreach ( $assets as $key => $unused ) { 131 if ( is_int( $key ) && $key >= 0 ) 132 unset( $assets[$key] ); 133 } 134 return $assets; 135 } 136 137 public function filter_html($content) { 138 $new_content = $content; 139 $assets = $this->parse_assets_from_html( $content ); 140 141 //workaround for srcset 142 if(isset($assets['img_srcset_url'])) { 143 foreach($assets['img_srcset_url'] as $pattern) { 144 if(strlen($pattern) === 0) 145 continue; 146 if($this->excluded_directory($pattern)) 147 continue; 148 $pattern_with_cdn_src = $this->rewrite_srcset($pattern); 149 $new_content = str_replace($pattern, $pattern_with_cdn_src, $new_content); 150 } 151 unset($assets['img_srcset_url']); 152 } 153 154 if ( ! empty( $assets ) ) { 155 foreach($assets as $type) { 156 foreach($type as $pattern) { 157 if(strlen($pattern) === 0) 158 continue; 159 if($this->excluded_directory($pattern)) 160 continue; 161 $pattern_with_cdn_src = $this->rewrite($pattern); 162 $new_content = str_replace($pattern, $pattern_with_cdn_src, $new_content); 163 } 164 } 165 } 166 return $new_content; 167 } 168 169 public function excluded_directory($url) { 170 $excludes = explode(",", get_option('DEX_EXCLUDES')); 171 foreach($excludes as $dir) { 172 if(!empty($dir)) { 173 if(strpos($url, $dir)) 174 return true; 175 } 176 } 177 return false; 178 } 179 } 24 var $host; 25 var $cdn; 26 var $options = array(); //dex_options 27 var $excludes = array(); // excludes 28 29 30 function __construct() 31 { 32 $this -> host = get_option('home'); 33 $opt = get_option( 'dex_cdn_options' ); 34 $this -> cdn = $opt['cdn_url']; 35 $exclude = get_option( 'dex_cdn_options' ); 36 $this-> excludes = $exclude['excludes']; 37 } 38 39 /** 40 * Function to activate the plugin 41 */ 42 function activate() { 43 $pluginOptions = get_option('dex_cdn_options'); 44 45 if ( !$pluginOptions ) { 46 add_option ( 'dex_cdn_options' , $this -> options ); 47 } 48 } 49 50 /** 51 * Erase options data when deactivate 52 */ 53 function deactivation() { 54 delete_option ( 'dex_cdn_options' ); 55 unregister_setting ( 'dex_cdn_settings' , 'dex_cdn_options' ); 56 } 57 58 /** 59 * Create the admin page options 60 */ 61 function dexecure_add_menu_options() { 62 add_options_page('Dexecure', 'Dexecure', 'manage_options', 'dexecure', array($this,'dexecure_output_page_content')); 63 } 64 65 /** 66 * Set the errors options 67 */ 68 function addNotices() { 69 settings_errors('dex_cdn_errors'); 70 } 71 72 /** 73 * Define the set of options 74 */ 75 function init(){ 76 register_setting ( 'dex_cdn_settings' , 'dex_cdn_options'); 77 } 78 79 function additionallCSS(){ 80 ?> 81 <style> 82 #wpfooter { 83 position: unset!important 84 } 85 </style> 86 <?php 87 } 88 89 /** 90 * Function to clean the inputs 91 * @param array $input from the form 92 * @return array with clean inputs 93 */ 94 function sanitize($input){ 95 add_settings_error( 96 'dex_cdn_errors', 97 'dex_cdn_success', 98 'Settings saved.', 99 'updated' 100 ); 101 102 return $input; 103 } 104 105 function dexecure_validate_cdn ( $url ) { 106 $cdn = esc_url_raw(sanitize_text_field($url)); 107 if(preg_match('@^https?:\/\/d[a-z0-9]+\.cloudfront\.net\/?$@i', $cdn)) 108 if(substr($cdn, -1) == '/') 109 return substr($cdn, 0, -1); 110 else 111 return $cdn; 112 else 113 return ''; 114 } 115 116 /** 117 * Function to create the page with form to config plugin 118 */ 119 function dexecure_output_page_content(){ 120 121 if( array_key_exists('dexecure-merge-nonce', $_POST) && wp_verify_nonce( $_POST['dexecure-merge-nonce'], 'dexecure-purge-merge-cache' ) && isset($_POST[ 'submit_hidden' ]) && $_POST[ 'submit_hidden' ] == 'Y' ) { 122 $dir = DEX_MMR_CACHE_DIR; 123 if(is_dir($dir)) { 124 foreach(glob($dir.'/{,.}*', GLOB_BRACE) as $file) { 125 if(basename($file) != '.' && basename($file) != '..') { 126 if(is_dir($file)) $this->rrmdir($file); else unlink($file); 127 } 128 } 129 rmdir($dir); 130 } 131 } 132 ?> 133 <div class="wrap"> 134 <h2>Menu</h2> 135 136 <form method="post" action="options.php" id="dex_cdn_form" > 137 <?php 138 settings_fields('dex_cdn_settings'); 139 140 $this -> options = get_option('dex_cdn_options'); 141 $this->options['cdn_url'] = $this->dexecure_validate_cdn($this->options['cdn_url']); 142 $this->options['excludes'] = sanitize_text_field($this->options['excludes']); 143 update_option('dex_cdn_options', $this->options); 144 145 146 if (!is_array($this->options)) 147 $this -> options = array(); 148 $opt = get_option( 'dex_cdn_options' ); 149 if(!empty($opt['excludes'])){ $opt_excl = $opt['excludes']; } else { $opt_excl = ''; } 150 151 if(!empty($opt['cdn_url'])){ $opt_val = $opt['cdn_url']; } else { $opt_val = ''; } 152 153 /* 154 if (!preg_match("~^(?:f|ht)tps?://~i", $opt_val)) { 155 $opt_val = "http://" . $opt_val; 156 }*/ 157 158 ?> 159 160 <div id="main" class="main"> 161 162 <div> 163 <h4>To serve your site assets from Dexecure:</h4> 164 Dexecure CDN: 165 <input type = "text" name = "dex_cdn_options[cdn_url]" id="cdn_url" value="<?php echo esc_attr($opt_val); ?>" size = "40" placeholder = "https://xyz.cloudfront.net" pattern="^([hH][tT][tT][pP][sS]?:\/\/)?[dD][a-zA-Z0-9]+\.[cC][lL][oO][uU][dD][fF][rR][oO][nN][tT]\.[nN][eE][tT]\/?$"> 166 </div> 167 <small>Add <b>http://</b> </small> 168 169 <h4>Exclusions:</h4> 170 <small>A comma separated list. eg: wp-content/plugins/unsafe1/,wp-content/plugins/unsafe2/file.js</small> 171 172 <div><label for="excludes"> 173 <textarea cols="50" rows="4" name="dex_cdn_options[excludes]" id="excludes"/><?php echo esc_attr($opt_excl); ?></textarea> 174 </label> 175 </div> 176 177 178 <h4>Choose which content will be retrieved from CDN:</h4> 179 180 181 <div class="chkbox"><label for="images"> 182 <input type="checkbox" id="images" name="dex_cdn_options[]" value="images"<?php if (in_array('images', $this->options)) echo ' checked="checked"' ?> />Images</label> 183 </div> 184 <div class="chkbox"><label for="contentcs"> 185 <input type="checkbox" id="contentcs" name="dex_cdn_options[]" value="contentcs"<?php if (in_array('contentcs', $this->options)) echo ' checked="checked"' ?> />CSS files</label> 186 </div> 187 188 <div class="chkbox"><label for="content"> 189 <input type="checkbox" id="content" name="dex_cdn_options[]" value="content"<?php if (in_array('content', $this->options)) echo ' checked="checked"' ?> />JS files</label> 190 </div> 191 192 193 194 </div> 195 196 <div class="submit"><input type="submit" name="submit" id="submit" class="button-primary" value="Save Changes" /></div> 197 </div> 198 </form> 199 200 <form name="form2" method="post" action=""> 201 <h4>When a CSS or JS file is modified, merged files are re-processed automatically. However, when a dependency changes these files may become stale.</h4> 202 203 <div> 204 <input type = "hidden" name = "submit_hidden" value = "Y"> 205 <input type = "submit" name = "purge-submit" class="button-secondary" value = "Purge Merged Files" /> 206 <?php wp_nonce_field('dexecure-purge-merge-cache', 'dexecure-merge-nonce') ?> 207 </form> 208 </div> 209 <?php 210 } 211 212 /** 213 * Start the buffer to get the content 214 */ 215 function pre_content() 216 { 217 ob_start(); 218 219 $this->merge_all_scripts(); 220 $this->merge_all_styles(); 221 222 } 223 224 /** 225 * Get the content from the buffer and parse it 226 */ 227 function post_content() 228 { 229 $html = ob_get_contents(); 230 ob_end_clean(); 231 232 echo $this->parse($html); 233 234 } 235 236 /** 237 * @param string $html 238 * Parse the original host into CDN host 239 */ 240 function parse($html) 241 { 242 243 $regex = array(); 244 245 $this -> options = get_option('dex_cdn_options'); 246 247 if ( $this -> cdn != $this -> host && is_array($this->options) && !empty($this->options)){ 248 //Images 249 if (in_array('images', $this->options)) 250 $regex['img'] = '/' . preg_quote($this->host , '/') . '\/(((?!gallery\.php)(?![\w-]+\/gallery-image))\S+\.(png|jpg|jpeg|gif|ico))/i'; 251 252 //CSS 253 if (in_array('contentcs', $this->options)) 254 $regex['contentcs'] = '/' . preg_quote($this->host , '/') . '\/(\S+\.(css))/i'; 255 256 //JS 257 if (in_array('content', $this->options)) 258 $regex['content'] = '/' . preg_quote($this->host , '/') . '\/(\S+\.(js))/i'; 259 260 //Exclusions 261 if(array_key_exists('excludes', $this->options) && !empty($this-> excludes)){ 262 $excludes = array_map('trim', explode(',', $this-> excludes)); 263 264 for( $i=0 ; $i<count($excludes) ; $i++ ){ 265 266 if(!empty( $excludes)){ 267 268 $regex1['excludes'] = $this->host.'/'.$excludes[$i]; 269 270 //print_r($regex1); 271 272 $html = str_replace( $regex1, $this->host.'\\'.$excludes[$i] , $html); 273 } 274 } 275 } 276 277 if(!empty($regex)) 278 $html = preg_replace( $regex , $this->cdn.'/$1' , $html); 279 280 281 } 282 return $html; 283 } 284 285 /** 286 * Remove query string from CSS/ JSS 287 */ 288 function dex_remove_version( $src ){ 289 $parts = explode( '?ver', $src ); 290 return $parts[0]; 291 } 292 293 /** 294 * Parse the original JS host into CDN host 295 */ 296 function merge_all_scripts() { 297 298 global $wp_scripts; 299 300 $this -> options = get_option('dex_cdn_options'); 301 302 if (in_array('comjsfile', $this->options)) { 303 304 $wp_scripts->all_deps($wp_scripts->queue); 305 306 $merged_file_location = get_stylesheet_directory() . DIRECTORY_SEPARATOR . 'dex-merged-script.js'; 307 308 $merged_script = ''; 309 310 // Loop javascript files and save to $merged_script variable 311 foreach( $wp_scripts->to_do as $handle) 312 { 313 314 $src = strtok($wp_scripts->registered[$handle]->src, '?'); 315 316 317 if (strpos($src, 'http') !== false) 318 { 319 320 $site_url = site_url(); 321 322 if (strpos($src, $site_url) !== false) 323 $js_file_path = str_replace($site_url, '', $src); 324 else 325 $js_file_path = $src; 326 327 $js_file_path = ltrim($js_file_path, '/'); 328 } 329 else 330 { 331 $js_file_path = ltrim($src, '/'); 332 } 333 334 if (file_exists($js_file_path)) 335 { 336 $localize = ''; 337 if (@key_exists('data', $wp_scripts->registered[$handle]->extra)) { 338 $localize = $obj->extra['data'] . ';'; 339 } 340 $merged_script .= $localize . file_get_contents($js_file_path) . ';'; 341 } 342 } 343 344 file_put_contents ( $merged_file_location , $merged_script); 345 346 wp_enqueue_script('merged-script', get_stylesheet_directory_uri() . '/dex-merged-script.js'); 347 348 foreach( $wp_scripts->to_do as $handle ) 349 { 350 wp_deregister_script($handle); 351 } 352 353 }// end if in_array 354 355 } 356 357 /** 358 * Parse the original CSS host into CDN host 359 */ 360 361 function merge_all_styles(){ 362 363 $this -> options = get_option('dex_cdn_options'); 364 365 //print_r($this -> options); 366 367 if (in_array('comcssfile', $this->options)) { 368 369 wp_styles(); 370 371 global $wp_styles; 372 373 $wp_styles->all_deps($wp_styles->queue); 374 375 $handles = $wp_styles->to_do; 376 377 $css_code = ''; 378 379 $merged_file_location = get_stylesheet_directory() . DIRECTORY_SEPARATOR . 'dex-merged-style.css'; 380 381 foreach ($handles as $handle) 382 { 383 384 $src = strtok($wp_styles->registered[$handle]->src, '?'); 385 386 if (strpos($src, 'http') !== false) 387 { 388 $site_url = site_url(); 389 390 if (strpos($src, $site_url) !== false) 391 $css_file_path = str_replace($site_url, '', $src); 392 else 393 $css_file_path = $src; 394 395 $css_file_path = ltrim($css_file_path, '/'); 396 } 397 else 398 { 399 $css_file_path = ltrim($src, '/'); 400 } 401 402 if (file_exists($css_file_path)) { 403 $css_code .= file_get_contents($css_file_path); 404 } 405 } 406 407 file_put_contents ( $merged_file_location , $css_code); 408 409 wp_enqueue_style('merged-style', get_stylesheet_directory_uri() . '/dex-merged-style.css'); 410 411 foreach ($handles as $handle) 412 { 413 wp_deregister_style($handle); 414 } 415 }//end if in_array 416 } 417 418 }// End Class
Note: See TracChangeset
for help on using the changeset viewer.