Plugin Directory

Changeset 1910167


Ignore:
Timestamp:
07/17/2018 06:52:37 AM (8 years ago)
Author:
dexecure
Message:

update to new version

Location:
dexecure
Files:
6 edited
1 copied

Legend:

Unmodified
Added
Removed
  • dexecure/tags/1.1/cdn-loader.php

    r1791690 r1910167  
    2424define("DEX_CDN_URL", "dex_cdn_url");
    2525if( ! defined( 'ABSPATH' ) ) {
    26     exit;
     26    exit;
    2727}
    28 
    29 require_once __DIR__ . '/src/merge-minify-refresh.php';
    30 $mergeminifyrefresh = new DexecureMergeMinifyRefresh();
    3128
    3229if(!defined('DEX_MMR_CACHE_DIR'))
    3330    define('DEX_MMR_CACHE_DIR', WP_CONTENT_DIR.'/dexecure-merge-cache');
    3431
    35 function dexecure_add_menu_options() {
    36     add_options_page( 'Dexecure', 'Dexecure', 'manage_options', 'dexecure', 'dexecure_output_page_content' );
     32require_once(dirname(__FILE__) . '/src/rewriter.php');
     33
     34global $url_rewriter;
     35$url_rewriter = new Dex_Rewrite();
     36
     37if (!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);
    3741}
    3842
    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 */
     44register_activation_hook ( __FILE__, array($url_rewriter , 'activate') );
     45register_deactivation_hook ( __FILE__, array($url_rewriter , 'deactivation') );
    4546
    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 */
     48add_action( 'admin_menu', array($url_rewriter,'dexecure_add_menu_options' ));
     49add_action( 'admin_notices', array($url_rewriter,'addNotices' ));
     50add_action ( 'admin_init' , array($url_rewriter , 'init' ));
     51//add_action ( 'admin_init' , array($url_rewriter , 'additionallCSS' ));
    5252
    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 );
    6955
    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 <?php
    92     }
    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 <?php
    117         $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 <?php
    133 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 <?php
    151 }
    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 true
    159     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  
    22Tags: Advanced website optimization
    33Requires at least: 3.6.1
    4 Tested up to: 4.8.4
    5 Stable tag: 1.0
     4Tested up to: 4.9.7
     5Stable tag: 1.1
    66License: GPLv2 or later
    77License URI: https://www.gnu.org/licenses/gpl-2.0.html
  • dexecure/tags/1.1/src/rewriter.php

    r1791690 r1910167  
    2020*/
    2121
    22 class Dex_Rewriter
     22class Dex_Rewrite
    2323{
    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  
    2424define("DEX_CDN_URL", "dex_cdn_url");
    2525if( ! defined( 'ABSPATH' ) ) {
    26     exit;
     26    exit;
    2727}
    28 
    29 require_once __DIR__ . '/src/merge-minify-refresh.php';
    30 $mergeminifyrefresh = new DexecureMergeMinifyRefresh();
    3128
    3229if(!defined('DEX_MMR_CACHE_DIR'))
    3330    define('DEX_MMR_CACHE_DIR', WP_CONTENT_DIR.'/dexecure-merge-cache');
    3431
    35 function dexecure_add_menu_options() {
    36     add_options_page( 'Dexecure', 'Dexecure', 'manage_options', 'dexecure', 'dexecure_output_page_content' );
     32require_once(dirname(__FILE__) . '/src/rewriter.php');
     33
     34global $url_rewriter;
     35$url_rewriter = new Dex_Rewrite();
     36
     37if (!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);
    3741}
    3842
    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 */
     44register_activation_hook ( __FILE__, array($url_rewriter , 'activate') );
     45register_deactivation_hook ( __FILE__, array($url_rewriter , 'deactivation') );
    4546
    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 */
     48add_action( 'admin_menu', array($url_rewriter,'dexecure_add_menu_options' ));
     49add_action( 'admin_notices', array($url_rewriter,'addNotices' ));
     50add_action ( 'admin_init' , array($url_rewriter , 'init' ));
     51//add_action ( 'admin_init' , array($url_rewriter , 'additionallCSS' ));
    5252
    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 );
    6955
    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 <?php
    92     }
    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 <?php
    117         $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 <?php
    133 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 <?php
    151 }
    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 true
    159     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  
    22Tags: Advanced website optimization
    33Requires at least: 3.6.1
    4 Tested up to: 4.8.4
    5 Stable tag: 1.0
     4Tested up to: 4.9.7
     5Stable tag: 1.1
    66License: GPLv2 or later
    77License URI: https://www.gnu.org/licenses/gpl-2.0.html
  • dexecure/trunk/src/rewriter.php

    r1791690 r1910167  
    2020*/
    2121
    22 class Dex_Rewriter
     22class Dex_Rewrite
    2323{
    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.