Plugin Directory

Changeset 2012339


Ignore:
Timestamp:
01/14/2019 09:20:16 PM (7 years ago)
Author:
piio
Message:

tagging version 0.9.16

Location:
piio-image-optimization
Files:
9 edited
9 copied

Legend:

Unmodified
Added
Removed
  • piio-image-optimization/tags/0.9.16/admin/class-piio-image-optimization-admin.php

    r2008456 r2012339  
    5656            $this->plugin_name = $plugin_name;
    5757            $this->version = $version;
     58            add_action('wp_ajax_piio_get_consumption', array($this, 'piio_ajax_get_consumption'));
     59        }
     60
     61        public function piio_ajax_get_consumption()
     62        {
     63            delete_option('piio_imageopt_consumption_status');
     64            delete_option('piio_imageopt_consumption_last_check');
     65            wp_die(); // this is required to return a proper result
    5866        }
    5967
     
    116124                        break;
    117125                }
     126                $check_again_link = "<a class='piio-link' href='#' id='piio_check_consumption_link'>Click here to check again</a>";
    118127                $consumption_css_class = $consumption_status === 'danger' ? 'error' : $show_consumption; ?>
    119                 <div class="notice piio-notice notice-<?php echo $consumption_css_class ?>">
     128                <div class="notice piio-notice consumption notice-<?php echo $consumption_css_class ?> is-dismissible">
    120129                    <p>
    121130                        <?= $consumption_status_text ?>
     131                        <br>
     132                        <?= $check_again_link ?>
    122133                    </p>
    123134                </div>
  • piio-image-optimization/tags/0.9.16/admin/css/piio-image-optimization-admin.css

    r1990962 r2012339  
    1111}
    1212.piio-notice p{
    13     font-size: 15px;
     13    /* font-size: 15px; */
     14}
     15.piio-notice a{
     16    font-weight: bold;
    1417}
    1518.piio-error {
  • piio-image-optimization/tags/0.9.16/admin/js/piio-image-optimization-admin.js

    r1990962 r2012339  
    11jQuery(document).ready(function() {
    2   // Show webP option if optimization is standard
    3   // var optimization = jQuery("#piio_imageopt_optimization");
    4   // if (optimization.length > 0) {
    5   //   showWebPOption(optimization[0].value);
    6   //   optimization.change(function() {
    7   //     showWebPOption(this.value);
    8   //   });
    9   // }
    10   //
    11   // function showWebPOption(value) {
    12   //   var webp = jQuery("#piio_imageopt_enable_webp");
    13   //   if (webp.length > 0) {
    14   //     var tr = webp.parent().parent();
    15   //     if (value == 1) {
    16   //       tr.hide();
    17   //     } else {
    18   //       tr.show();
    19   //     }
    20   //   }
    21   // }
    22 
    232  // Validate if key is set when Piio is enabled
    243  jQuery("#piio_imageopt_enabled").closest("form").submit(function(event) {
     
    3817    }
    3918  })
     19
     20  jQuery("#piio_check_consumption_link").click(function(event) {
     21    event.preventDefault();
     22    var data = {
     23      'action': 'piio_get_consumption'
     24    };
     25
     26    jQuery.post(ajaxurl, data, function() {
     27      location.reload();
     28    });
     29  });
    4030});
  • piio-image-optimization/tags/0.9.16/includes/class-piio-image-optimization-callbacks.php

    r1970031 r2012339  
    22
    33/**
    4 * Register all actions and filters for the plugin
     4* Has callbacks helpers for the plugin.
    55*
    66* @link       https://piio.co
     
    1212
    1313/**
    14 * Register all actions and filters for the plugin.
    15 *
    16 * Maintain a list of all hooks that are registered throughout
    17 * the plugin, and register them with the WordPress API. Call the
    18 * run function to execute the list of actions and filters.
     14* Has callbacks helpers for the plugin.
    1915*
    2016* @package    Piio_Image_Optimization
  • piio-image-optimization/tags/0.9.16/includes/class-piio-image-optimization.php

    r2008456 r2012339  
    7474                $this->version = PIIO_IMAGE_OPTIMIZATION_VERSION;
    7575            } else {
    76                 $this->version = '0.9.15';
     76                $this->version = '0.9.16';
    7777            }
    7878            $this->plugin_name = 'piio-image-optimization';
     
    109109            */
    110110            require_once plugin_dir_path(dirname(__FILE__)) . 'includes/class-piio-image-optimization-loader.php';
     111
     112            /**
     113            * The class is a helper to deal with urls
     114            */
     115            require_once plugin_dir_path(dirname(__FILE__)) . 'includes/class-piio-image-optimization-url-helper.php';
    111116
    112117            /**
  • piio-image-optimization/tags/0.9.16/piio-image-optimization.php

    r2008456 r2012339  
    1313* Plugin URI:        https://piio.co/wordpress
    1414* Description:       Generates responsive and optimized images, so you don't have to.
    15 * Version:           0.9.15
     15* Version:           0.9.16
    1616* Author:            Piio, Inc.
    1717* Author URI:        https://piio.co
     
    3030* Currently plugin version.
    3131*/
    32 define('PIIO_IMAGE_OPTIMIZATION_VERSION', '0.9.15');
     32define('PIIO_IMAGE_OPTIMIZATION_VERSION', '0.9.16');
    3333
    3434/**
  • piio-image-optimization/tags/0.9.16/public/class-piio-image-optimization-public.php

    r2007819 r2012339  
    7878        public function get_largest_image_src($imgTag)
    7979        {
    80             //If tag contains srcset
    81             if (strpos($imgTag, 'srcset') !== false) {
    82                 preg_match('/\bsrcset\W*=\W*[\'"](.*)?[\'"]/Uxis', $imgTag, $matches);
    83                 //Get all sources
     80            // If tag contains srcset
     81            if (preg_match('/\bsrcset\W*=\W*[\'"](.*)?[\'"]/Uxis', $imgTag, $matches)) {
     82                // Get all sources
    8483                $sources = array_map('trim', explode(',', $matches[1]));
    8584                $size = 0;
    8685                foreach ($sources as $source) {
    87                     //Extract url and size
     86                    // Extract url and size
    8887                    $attr = array_map('trim', explode(' ', $source));
    89                     //Check if we have size with unit
     88                    // Check if we have size with unit
    9089                    if ($attr[1]) {
    91                         //url = $attr[0], size with unit = $attr[1]
    92                         //remove unit (w or x)
     90                        // url = $attr[0], size with unit = $attr[1]
     91                        // remove unit (w or x)
    9392                        $attr[1] = intval(substr($attr[1], 0, strlen($attr[1]) - 1));
    9493                        if ($attr[1] > $size) {
     
    9998                }
    10099                if (isset($retSrc)) {
    101                     return $this->_url_to_absolute($retSrc);
    102                 }
    103             }
    104             //Else just return src
     100                    return Piio_Image_Optimization_File_Helper::url_to_absolute($retSrc);
     101                }
     102            }
     103            // Else just return src
    105104            preg_match('/\bsrc\W*=\W*[\'"](.*)?[\'"]/Uxis', $imgTag, $matches);
    106             return (isset($matches[1])) ? $this->_url_to_absolute($matches[1]) : null;
     105            return (isset($matches[1])) ? Piio_Image_Optimization_File_Helper::url_to_absolute($matches[1]) : null;
    107106        }
    108107
     
    110109        {
    111110            // Get consumption
    112             $consumption = $this->get_consumption();
     111            $consumption = $this->_check_consumption();
    113112
    114113            // Check for standard or adv optimization
    115114            $optimization = get_option('piio_imageopt_optimization');
    116             $use_data_piio = isset($optimization[0]) ? ($optimization[0] === "1") : true;
    117 
    118             // Change tags if adv optimization or consumption is not in danger
    119             $consumption_ok = $use_data_piio || ($consumption !== 'danger');
     115            $adv_optimization = isset($optimization[0]) ? ($optimization[0] === "1") : true;
     116
     117            // Replace tags if adv optimization (js will take care of it) or consumption is not in danger
     118            $replace_tags = $adv_optimization || ($consumption !== 'danger');
    120119
    121120            // Check if optimize for editors is set
     
    128127            $is_admin = is_admin();
    129128
    130             if ($consumption_ok && !$is_admin && !$editor) {
    131                 //Get optimization option and api key
     129            if ($replace_tags && !$is_admin && !$editor) {
     130                // Get api key
    132131                $api_key = get_option('piio_imageopt_api_key');
    133 
    134                 $HTMLContent = $this->_replace_img_tags($HTMLContent, $use_data_piio, $api_key);
    135 
     132                // Check if webP is enabled
     133                $enable_webp = get_option('piio_imageopt_enable_webp');
     134                $enable_webp = isset($enable_webp[0]) ? ($enable_webp[0] === "1") : true;
     135                // Check if browser accepts webP
     136                $client_accept_webp = strpos($_SERVER['HTTP_ACCEPT'], 'image/webp') !== false;
     137
     138                $HTMLContent = $this->_replace_img_tags($HTMLContent, $adv_optimization, $api_key, $enable_webp, $client_accept_webp);
     139
     140                // Check if we have to optimize background images
    136141                $optimize_bck = get_option('piio_imageopt_optimize_bck');
    137142                $optimize_bck = isset($optimize_bck[0]) ? ($optimize_bck[0] === "1") : true;
    138143
    139144                if ($optimize_bck) {
    140                     $HTMLContent = $this->_replace_bck_styles($HTMLContent, $use_data_piio, $api_key);
     145                    $HTMLContent = $this->_replace_bck_styles($HTMLContent, $adv_optimization, $api_key, $enable_webp, $client_accept_webp);
    141146                }
    142147            }
     
    178183        }
    179184
    180         public function get_consumption()
     185        private function _check_consumption()
    181186        {
    182187            $piio_consumption_last_check = get_option('piio_imageopt_consumption_last_check');
    183             $check = false;
     188            $retrieve = false;
    184189            $now = date("Y-m-d");
    185190
    186191            // If no option or more than one day, check again
    187192            if (!$piio_consumption_last_check) {
    188                 $check = true;
     193                $retrieve = true;
    189194            } else {
    190195                $diffInDays = intval($this->_date_difference($piio_consumption_last_check, $now), 10);
    191                 $check = ($diffInDays > 1);
    192             }
    193 
    194             if ($check) {
    195                 // Request Piio for consumption
    196                 $api_key = get_option('piio_imageopt_api_key');
    197                 if ($api_key) {
    198                     $url = "https://app.piio.co/consumptionStatus/" . $api_key;
    199                     $response = wp_remote_get($url);
    200                     if (!is_wp_error($response)) {
    201                         if (isset($response['body'])) {
    202                             $response = json_decode($response['body']);
    203                             update_option('piio_imageopt_consumption_last_check', $now);
    204                             if ($response->status == 200) {
    205                                 update_option('piio_imageopt_consumption_status', $response->message);
    206                             }
    207                         }
     196                $retrieve = $diffInDays > 1;
     197            }
     198
     199            if ($retrieve) {
     200                // Retrieve consumption from server
     201                $this->_retrieve_consumption();
     202            }
     203
     204            return get_option('piio_imageopt_consumption_status');
     205        }
     206
     207        private function _retrieve_consumption()
     208        {
     209            // Request Piio for consumption
     210            $api_key = get_option('piio_imageopt_api_key');
     211            if ($api_key) {
     212                $url = "https://app.piio.co/consumptionStatus/" . $api_key;
     213                $response = wp_remote_get($url);
     214                if (!is_wp_error($response) && isset($response['body'])) {
     215                    $response = json_decode($response['body']);
     216                    $now = date("Y-m-d");
     217                    update_option('piio_imageopt_consumption_last_check', $now);
     218                    if ($response->status == 200) {
     219                        update_option('piio_imageopt_consumption_status', $response->message);
    208220                    }
    209221                }
    210222            }
    211 
    212             return get_option('piio_imageopt_consumption_status');
    213223        }
    214224
     
    222232        }
    223233
    224         private function _replace_img_tags($HTMLContent, $use_data_piio, $api_key)
    225         {
    226             $placeholder_url = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8+f9vPQAJZAN2rlRQVAAAAABJRU5ErkJggg==";
    227             $matches = array();
    228             preg_match_all('/<img[\s\r\n]+.*?>/is', $HTMLContent, $matches);
     234        private function _replace_img_tags($HTMLContent, $adv_optimization, $api_key, $enable_webp, $client_accept_webp)
     235        {
     236            $placeholder = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
     237            $img_tags_matches = array();
     238            preg_match_all('/<img[\s\r\n]+.*?>/is', $HTMLContent, $img_tags_matches);
    229239
    230240            $search = array();
     
    233243            $std_opt_img_added = false;
    234244
    235             $i = 0;
    236             foreach ($matches[0] as $imgHTML) {
    237                 // don't to the replacement if the image is a data-uri or has class piio-skip
     245            foreach ($img_tags_matches[0] as $imgHTML) {
     246                // Get largest image src
    238247                $src = $this->get_largest_image_src($imgHTML);
    239248
     249                // Don't to the replacement if the image is a data-uri or has class piio-skip
    240250                if (!preg_match("/data:image/is", $src) && !preg_match("/class=(['\"]|(['\"][^'\"]*)\s)piio-skip(['\"]|\s([^'\"]*)['\"])/is", $imgHTML)) {
    241                     $i++;
    242 
    243                     // get largest image src
    244 
    245                     $replaceHTML = '';
    246 
    247                     if ($use_data_piio) {
    248                         // advanced optimization enabled
    249 
    250                         // replace the src and add the data-piio attribute
    251                         $replaceHTML = preg_replace('/<img(.*?)src=(["\'])(.*?)["\']/is', '<img$1src=$2' . $placeholder_url . '$2 data-piio=$2' . urldecode($src) . "$2", $imgHTML);
    252                         // remove srcset and sizes attributes
    253                         $replaceHTML = preg_replace('/<img(.*?)srcset=["\'].*?["\']/is', '<img$1', $replaceHTML);
    254                         $replaceHTML = preg_replace('/<img(.*?)sizes=["\'].*?["\']/is', '<img$1', $replaceHTML);
     251                    if ($adv_optimization) {
     252                        // Advanced optimization enabled
     253                        $replaceHTML = $this->_advanced_mode($imgHTML, $src, $placeholder);
    255254                    } else {
    256                         // standard optimization enabled
    257 
    258                         $enable_webp = get_option('piio_imageopt_enable_webp');
    259                         $enable_webp = isset($enable_webp[0]) ? ($enable_webp[0] === "1") : true;
    260 
    261                         $params = '';
    262                         //Check if client is using Chrome
    263                         if ($enable_webp && preg_match('/(Chrome)\//i', $_SERVER['HTTP_USER_AGENT']) && !preg_match('/(Aviator|ChromePlus|coc_|Dragon|Edge|Flock|Iron|Kinza|Maxthon|MxNitro|Nichrome|OPR|Perk|Rockmelt|Seznam|Sleipnir|Spark|UBrowser|Vivaldi|WebExplorer|YaBrowser)/i', $_SERVER['HTTP_USER_AGENT'])) {
    264                             $params .= 'wp,1';
    265                         }
    266 
    267                         // remove srcset and sizes attributes as we are adding our own
    268                         $replaceHTML = preg_replace('/<img(.*?)srcset=["\'].*?["\']/is', '<img$1', $imgHTML);
    269                         $replaceHTML = preg_replace('/<img(.*?)sizes=["\'].*?["\']/is', '<img$1', $replaceHTML);
    270 
    271                         $srcAttr = urlencode($src);
    272 
    273                         $breakpoints = array("576", "768", "992", "1200");
    274                         $srcset_values = array();
    275                         foreach ($breakpoints as $width) {
    276                             $local_params = 'vw,' . $width . (($params != '') ? ',' . $params : '');
    277                             array_push($srcset_values, 'https://pcdn.piiojs.com/i/' . $api_key . '/' . $local_params . '/' . $srcAttr . ' ' . $width . 'w');
    278                         }
    279                         // replace src with largest image and add srcset
    280                         $replaceHTML = preg_replace('/<img(.*?)src=(["\'])(.*?)["\']/is', '<img$1src=$2' . 'https://pcdn.piiojs.com/i/' . $api_key . (($params != '') ? '/' . $params : '') . '/' . $srcAttr . '$2 srcset=$2' . implode(', ', $srcset_values) . '$2', $replaceHTML);
    281 
    282                         // add img with data-piio to log user data for consumption
     255                        // Standard optimization enabled
     256                        $replaceHTML = $this->_standard_mode($imgHTML, $src, $api_key, $enable_webp, $client_accept_webp);
     257
     258                        // Add img with data-piio to log user data for consumption
    283259                        if (!$std_opt_img_added) {
    284                             $body_matches = array();
    285                             if (preg_match('/<body.*?>/is', $HTMLContent, $body_matches, PREG_OFFSET_CAPTURE) > 0) {
    286                                 // get <body start position
    287                                 // body_matches[0][0] contains string, body_matches[0][1] contains string index
    288                                 $body_end_pos = $body_matches[0][1] + strlen($body_matches[0][0]);
    289                                 $HTMLContent = substr_replace($HTMLContent, $this->_get_transparent_svg_with_piio(), $body_end_pos, 0);
    290                             };
     260                            $HTMLContent = $this->_add_data_piio_img($HTMLContent);
    291261                            $std_opt_img_added = true;
    292262                        }
     
    304274        }
    305275
    306         private function _replace_bck_styles($HTMLContent, $use_data_piio, $api_key)
     276        private function _replace_bck_styles($HTMLContent, $adv_optimization, $api_key, $enable_webp, $client_accept_webp)
    307277        {
    308278            $matches = array();
     
    312282            $replace = array();
    313283
    314             $i = 0;
     284            $params = "";
     285            // Set wp param is webP is enabled
     286            if ($enable_webp && $client_accept_webp) {
     287                $params .= "wp,1";
     288            }
     289            $callback = new Piio_Image_Optimization_Callbacks($api_key, $params);
     290
    315291            foreach ($matches[0] as $bckHTML) {
    316                 // don't to the replacement if the image is a data-uri or has class piio-skip
     292                // Don't to the replacement if the image is a data-uri or has class piio-skip
    317293                if (!preg_match("/url\(['\"]data:image/is", $bckHTML) && !preg_match("/class=(['\"]|(['\"][^'\"]*)\s)piio-skip(['\"]|\s([^'\"]*)['\"])/is", $bckHTML)) {
    318                     $i++;
    319 
    320294                    $replaceHTML = '';
    321295
    322                     if ($use_data_piio) {
    323                         // replace the background-image attribute from style and add the data-piio-bck attribute
    324                         $replaceHTML = preg_replace("/(\sstyle=['\"][^>]*?)(background-image:.*?url\((\s*.*?\s*)\));?(.*?['\"])/is", '$1$4 data-piio-bck=' . urldecode("$3"), $bckHTML);
    325                         $replaceHTML = preg_replace("/(\sstyle=['\"][^>]*?background:.*?)(url\((\s*.*?\s*)\));?(.*?['\"])/is", '$1$4 data-piio-bck=' . urldecode("$3"), $replaceHTML);
     296                    if ($adv_optimization) {
     297                        // Replace the background-image attribute from style and add the data-piio-bck attribute
     298                        $replaceHTML = preg_replace("/(\sstyle=['\"][^>]*?)(background-image:.*?url\((\s*.*?\s*)\));?(.*?['\"])/is", '$1$4 data-piio-bck=$3', $bckHTML);
     299                        $replaceHTML = preg_replace("/(\sstyle=['\"][^>]*?background:.*?)(url\((\s*.*?\s*)\));?(.*?['\"])/is", '$1$4 data-piio-bck=$3', $replaceHTML);
    326300                    } else {
    327                         $enable_webp = get_option('piio_imageopt_enable_webp');
    328                         $enable_webp = isset($enable_webp[0]) ? ($enable_webp[0] === "1") : true;
    329 
    330                         $params = "";
    331                         //Check if client is using Chrome
    332                         if ($enable_webp && preg_match('/(Chrome)\//i', $_SERVER['HTTP_USER_AGENT']) && !preg_match('/(Aviator|ChromePlus|coc_|Dragon|Edge|Flock|Iron|Kinza|Maxthon|MxNitro|Nichrome|OPR|Perk|Rockmelt|Seznam|Sleipnir|Spark|UBrowser|Vivaldi|WebExplorer|YaBrowser)/i', $_SERVER['HTTP_USER_AGENT'])) {
    333                             $params .= "wp,1";
    334                         }
    335 
    336                         $callback = new Piio_Image_Optimization_Callbacks($api_key, $params);
    337 
     301                        // Using callback because of replace length
    338302                        $replaceHTML = preg_replace_callback("/(\sstyle=['\"][^>]*?)(background-image:.*?url\(['\"](\s*.*?\s*)['\"]\));?(.*?['\"])/is", array($callback, 'callback_background_image'), $bckHTML);
    339 
    340303                        $replaceHTML = preg_replace_callback("/(\sstyle=['\"][^>]*?background:.*?url\(['\"])(\s*.*?\s*)(['\"]\);?.*?['\"])/is", array($callback, 'callback_background'), $replaceHTML);
    341304                    }
     
    354317        private function _get_transparent_svg_with_piio()
    355318        {
    356             return "<img src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8+f9vPQAJZAN2rlRQVAAAAABJRU5ErkJggg==' data-piio='" . plugin_dir_url(__FILE__) . 'images/transparent.svg' . "' style='width:1px !important;height:1px !important;position:absolute !important;top:0 !important;left:-1px !important'>";
    357         }
    358 
    359         private function _url_to_absolute($relativeUrl)
    360         {
    361             $baseUrl = get_site_url();
    362             // If relative URL has a scheme, clean path and return.
    363             $r = parse_url($relativeUrl);
    364             if ($r === false) {
    365                 return false;
    366             }
    367             if (!empty($r['scheme'])) {
    368                 if (!empty($r['path']) && $r['path'][0] == '/') {
    369                     $r['path'] = $this->_url_remove_dot_segments($r['path']);
    370                 }
    371                 return $this->_join_url($r);
    372             }
    373 
    374             // Make sure the base URL is absolute.
    375             $b = parse_url($baseUrl);
    376             if ($b === false || empty($b['scheme']) || empty($b['host'])) {
    377                 return false;
    378             }
    379             $r['scheme'] = $b['scheme'];
    380 
    381             // If relative URL has an authority, clean path and return.
    382             if (isset($r['host'])) {
    383                 if (!empty($r['path'])) {
    384                     $r['path'] = $this->_url_remove_dot_segments($r['path']);
    385                 }
    386                 return $this->_join_url($r);
    387             }
    388             unset($r['port']);
    389             unset($r['user']);
    390             unset($r['pass']);
    391 
    392             // Copy base authority.
    393             $r['host'] = $b['host'];
    394             if (isset($b['port'])) {
    395                 $r['port'] = $b['port'];
    396             }
    397             if (isset($b['user'])) {
    398                 $r['user'] = $b['user'];
    399             }
    400             if (isset($b['pass'])) {
    401                 $r['pass'] = $b['pass'];
    402             }
    403 
    404             // If relative URL has no path, use base path
    405             if (empty($r['path'])) {
    406                 if (!empty($b['path'])) {
    407                     $r['path'] = $b['path'];
    408                 }
    409                 if (!isset($r['query']) && isset($b['query'])) {
    410                     $r['query'] = $b['query'];
    411                 }
    412                 return $this->_join_url($r);
    413             }
    414 
    415             // If relative URL path doesn't start with /, merge with base path
    416             if ($r['path'][0] != '/') {
    417                 $base = mb_strrchr($b['path'], '/', true, 'UTF-8');
    418                 if ($base === false) {
    419                     $base = '';
    420                 }
    421                 $r['path'] = $base . '/' . $r['path'];
    422             }
    423             $r['path'] = $this->_url_remove_dot_segments($r['path']);
    424             return $this->_join_url($r);
    425         }
    426 
    427         private function _join_url($parts, $encode = true)
    428         {
    429             if ($encode) {
    430                 if (isset($parts['user'])) {
    431                     $parts['user'] = rawurlencode($parts['user']);
    432                 }
    433                 if (isset($parts['pass'])) {
    434                     $parts['pass'] = rawurlencode($parts['pass']);
    435                 }
    436                 if (isset($parts['host']) && !preg_match('!^(\[[\da-f.:]+\]])|([\da-f.:]+)$!ui', $parts['host'])) {
    437                     $parts['host'] = rawurlencode($parts['host']);
    438                 }
    439                 if (!empty($parts['path'])) {
    440                     $parts['path'] = preg_replace('!%2F!ui', '/', rawurlencode($parts['path']));
    441                 }
    442                 if (isset($parts['query'])) {
    443                     $parts['query'] = rawurlencode($parts['query']);
    444                 }
    445                 if (isset($parts['fragment'])) {
    446                     $parts['fragment'] = rawurlencode($parts['fragment']);
    447                 }
    448             }
    449 
    450             $url = '';
    451             if (!empty($parts['scheme'])) {
    452                 $url .= $parts['scheme'] . ':';
    453             }
    454             if (isset($parts['host'])) {
    455                 $url .= '//';
    456                 if (isset($parts['user'])) {
    457                     $url .= $parts['user'];
    458                     if (isset($parts['pass'])) {
    459                         $url .= ':' . $parts['pass'];
    460                     }
    461                     $url .= '@';
    462                 }
    463                 if (preg_match('!^[\da-f]*:[\da-f.:]+$!ui', $parts['host'])) {
    464                     $url .= '[' . $parts['host'] . ']'; // IPv6
    465                 } else {
    466                     $url .= $parts['host'];             // IPv4 or name
    467                 }
    468                 if (isset($parts['port'])) {
    469                     $url .= ':' . $parts['port'];
    470                 }
    471                 if (!empty($parts['path']) && $parts['path'][0] != '/') {
    472                     $url .= '/';
    473                 }
    474             }
    475             if (!empty($parts['path'])) {
    476                 $url .= $parts['path'];
    477             }
    478             if (isset($parts['query'])) {
    479                 $url .= '?' . $parts['query'];
    480             }
    481             if (isset($parts['fragment'])) {
    482                 $url .= '#' . $parts['fragment'];
    483             }
    484             return $url;
    485         }
    486 
    487         private function _url_remove_dot_segments($path)
    488         {
    489             // multi-byte character explode
    490             $inSegs = preg_split('!/!u', $path);
    491             $outSegs = array( );
    492             foreach ($inSegs as $seg) {
    493                 if ($seg == '' || $seg == '.') {
    494                     continue;
    495                 }
    496                 if ($seg == '..') {
    497                     array_pop($outSegs);
    498                 } else {
    499                     array_push($outSegs, $seg);
    500                 }
    501             }
    502             $outPath = implode('/', $outSegs);
    503             if ($path[0] == '/') {
    504                 $outPath = '/' . $outPath;
    505             }
    506             // compare last multi-byte character against '/'
    507             if ($outPath != '/' && (mb_strlen($path)-1) == mb_strrpos($path, '/', 'UTF-8')) {
    508                 $outPath .= '/';
    509             }
    510             return $outPath;
     319            return "<img src='data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7' data-piio='" . plugin_dir_url(__FILE__) . 'images/transparent.svg' . "' style='width:1px !important;height:1px !important;position:absolute !important;top:0 !important;left:-1px !important'>";
     320        }
     321
     322        private function _advanced_mode($imgHTML, $src, $placeholder)
     323        {
     324            // Remove srcset and sizes attributes
     325            $replaceHTML = preg_replace('/<img(.*?)srcset=["\'].*?["\']/is', '<img$1', $imgHTML);
     326            $replaceHTML = preg_replace('/<img(.*?)sizes=["\'].*?["\']/is', '<img$1', $replaceHTML);
     327
     328            // Replace the src with the data-piio attribute
     329            $replaceHTML = preg_replace('/<img(.*?)src=(["\']).*?["\']/is', '<img$1src=$2' . $placeholder . '$2 data-piio=$2' . $src . "$2", $replaceHTML);
     330
     331            return $replaceHTML;
     332        }
     333
     334        private function _standard_mode($imgHTML, $src, $api_key, $enable_webp, $client_accept_webp)
     335        {
     336            $srcAttr = urlencode($src);
     337
     338            // Remove srcset and sizes attributes as we are adding our own
     339            $replaceHTML = preg_replace('/<img(.*?)srcset=["\'].*?["\']/is', '<img$1', $imgHTML);
     340            $replaceHTML = preg_replace('/<img(.*?)sizes=["\'].*?["\']/is', '<img$1', $replaceHTML);
     341
     342            // Check if image is an svg
     343            if (pathinfo($srcAttr, PATHINFO_EXTENSION) == 'svg') {
     344                $replaceHTML = preg_replace('/<img(.*?)src=(["\']).*?["\']/is', '<img$1src=$2' . 'https://pcdn.piiojs.com/i/' . $api_key . '/' . $srcAttr . "$2", $replaceHTML);
     345            } else {
     346                $params = '';
     347                // Set wp param is webP is enabled
     348                if ($enable_webp && $client_accept_webp) {
     349                    $params .= 'wp,1,';
     350                }
     351
     352                $breakpoints = array("576", "768", "992", "1200");
     353                $srcset_values = array();
     354                foreach ($breakpoints as $width) {
     355                    $local_params = $params . 'vw,' . $width;
     356                    array_push($srcset_values, 'https://pcdn.piiojs.com/i/' . $api_key . '/' . $local_params . '/' . $srcAttr . ' ' . $width . 'w');
     357                }
     358                // Replace src with largest image and add srcset
     359                $replaceHTML = preg_replace('/<img(.*?)src=(["\']).*?["\']/is', '<img$1src=$2' . 'https://pcdn.piiojs.com/i/' . $api_key . (($params != '') ? '/' . $params : '') . '/' . $srcAttr . '$2 srcset=$2' . implode(', ', $srcset_values) . '$2', $replaceHTML);
     360            }
     361
     362            return $replaceHTML;
     363        }
     364
     365        private function _add_data_piio_img($HTMLContent)
     366        {
     367            $body_matches = array();
     368            if (preg_match('/<body.*?>/is', $HTMLContent, $body_matches, PREG_OFFSET_CAPTURE) > 0) {
     369                // Get <body start position
     370                // Body_matches[0][0] contains string, body_matches[0][1] contains string index
     371                $body_end_pos = $body_matches[0][1] + strlen($body_matches[0][0]);
     372                $HTMLContent = substr_replace($HTMLContent, $this->_get_transparent_svg_with_piio(), $body_end_pos, 0);
     373            };
     374            return $HTMLContent;
    511375        }
    512376    }
  • piio-image-optimization/tags/0.9.16/readme.txt

    r2008456 r2012339  
    66Requires PHP: 5.3.0
    77Tested up to: 5.0
    8 Stable tag: 0.9.15
     8Stable tag: 0.9.16
    99License: GPLv2 or later
    1010License URI: http://www.gnu.org/licenses/gpl-2.0.html
     
    125125
    126126== Changelog ==
     127= 0.9.16 =
     128* Check consumption status manually
    127129= 0.9.15 =
    128130* Improved compatibility with cache plugins
  • piio-image-optimization/trunk/admin/class-piio-image-optimization-admin.php

    r2008456 r2012339  
    5656            $this->plugin_name = $plugin_name;
    5757            $this->version = $version;
     58            add_action('wp_ajax_piio_get_consumption', array($this, 'piio_ajax_get_consumption'));
     59        }
     60
     61        public function piio_ajax_get_consumption()
     62        {
     63            delete_option('piio_imageopt_consumption_status');
     64            delete_option('piio_imageopt_consumption_last_check');
     65            wp_die(); // this is required to return a proper result
    5866        }
    5967
     
    116124                        break;
    117125                }
     126                $check_again_link = "<a class='piio-link' href='#' id='piio_check_consumption_link'>Click here to check again</a>";
    118127                $consumption_css_class = $consumption_status === 'danger' ? 'error' : $show_consumption; ?>
    119                 <div class="notice piio-notice notice-<?php echo $consumption_css_class ?>">
     128                <div class="notice piio-notice consumption notice-<?php echo $consumption_css_class ?> is-dismissible">
    120129                    <p>
    121130                        <?= $consumption_status_text ?>
     131                        <br>
     132                        <?= $check_again_link ?>
    122133                    </p>
    123134                </div>
  • piio-image-optimization/trunk/admin/css/piio-image-optimization-admin.css

    r1990962 r2012339  
    1111}
    1212.piio-notice p{
    13     font-size: 15px;
     13    /* font-size: 15px; */
     14}
     15.piio-notice a{
     16    font-weight: bold;
    1417}
    1518.piio-error {
  • piio-image-optimization/trunk/admin/js/piio-image-optimization-admin.js

    r1990962 r2012339  
    11jQuery(document).ready(function() {
    2   // Show webP option if optimization is standard
    3   // var optimization = jQuery("#piio_imageopt_optimization");
    4   // if (optimization.length > 0) {
    5   //   showWebPOption(optimization[0].value);
    6   //   optimization.change(function() {
    7   //     showWebPOption(this.value);
    8   //   });
    9   // }
    10   //
    11   // function showWebPOption(value) {
    12   //   var webp = jQuery("#piio_imageopt_enable_webp");
    13   //   if (webp.length > 0) {
    14   //     var tr = webp.parent().parent();
    15   //     if (value == 1) {
    16   //       tr.hide();
    17   //     } else {
    18   //       tr.show();
    19   //     }
    20   //   }
    21   // }
    22 
    232  // Validate if key is set when Piio is enabled
    243  jQuery("#piio_imageopt_enabled").closest("form").submit(function(event) {
     
    3817    }
    3918  })
     19
     20  jQuery("#piio_check_consumption_link").click(function(event) {
     21    event.preventDefault();
     22    var data = {
     23      'action': 'piio_get_consumption'
     24    };
     25
     26    jQuery.post(ajaxurl, data, function() {
     27      location.reload();
     28    });
     29  });
    4030});
  • piio-image-optimization/trunk/includes/class-piio-image-optimization-callbacks.php

    r1970031 r2012339  
    22
    33/**
    4 * Register all actions and filters for the plugin
     4* Has callbacks helpers for the plugin.
    55*
    66* @link       https://piio.co
     
    1212
    1313/**
    14 * Register all actions and filters for the plugin.
    15 *
    16 * Maintain a list of all hooks that are registered throughout
    17 * the plugin, and register them with the WordPress API. Call the
    18 * run function to execute the list of actions and filters.
     14* Has callbacks helpers for the plugin.
    1915*
    2016* @package    Piio_Image_Optimization
  • piio-image-optimization/trunk/includes/class-piio-image-optimization.php

    r2008456 r2012339  
    7474                $this->version = PIIO_IMAGE_OPTIMIZATION_VERSION;
    7575            } else {
    76                 $this->version = '0.9.15';
     76                $this->version = '0.9.16';
    7777            }
    7878            $this->plugin_name = 'piio-image-optimization';
     
    109109            */
    110110            require_once plugin_dir_path(dirname(__FILE__)) . 'includes/class-piio-image-optimization-loader.php';
     111
     112            /**
     113            * The class is a helper to deal with urls
     114            */
     115            require_once plugin_dir_path(dirname(__FILE__)) . 'includes/class-piio-image-optimization-url-helper.php';
    111116
    112117            /**
  • piio-image-optimization/trunk/piio-image-optimization.php

    r2008456 r2012339  
    1313* Plugin URI:        https://piio.co/wordpress
    1414* Description:       Generates responsive and optimized images, so you don't have to.
    15 * Version:           0.9.15
     15* Version:           0.9.16
    1616* Author:            Piio, Inc.
    1717* Author URI:        https://piio.co
     
    3030* Currently plugin version.
    3131*/
    32 define('PIIO_IMAGE_OPTIMIZATION_VERSION', '0.9.15');
     32define('PIIO_IMAGE_OPTIMIZATION_VERSION', '0.9.16');
    3333
    3434/**
  • piio-image-optimization/trunk/public/class-piio-image-optimization-public.php

    r2007819 r2012339  
    7878        public function get_largest_image_src($imgTag)
    7979        {
    80             //If tag contains srcset
    81             if (strpos($imgTag, 'srcset') !== false) {
    82                 preg_match('/\bsrcset\W*=\W*[\'"](.*)?[\'"]/Uxis', $imgTag, $matches);
    83                 //Get all sources
     80            // If tag contains srcset
     81            if (preg_match('/\bsrcset\W*=\W*[\'"](.*)?[\'"]/Uxis', $imgTag, $matches)) {
     82                // Get all sources
    8483                $sources = array_map('trim', explode(',', $matches[1]));
    8584                $size = 0;
    8685                foreach ($sources as $source) {
    87                     //Extract url and size
     86                    // Extract url and size
    8887                    $attr = array_map('trim', explode(' ', $source));
    89                     //Check if we have size with unit
     88                    // Check if we have size with unit
    9089                    if ($attr[1]) {
    91                         //url = $attr[0], size with unit = $attr[1]
    92                         //remove unit (w or x)
     90                        // url = $attr[0], size with unit = $attr[1]
     91                        // remove unit (w or x)
    9392                        $attr[1] = intval(substr($attr[1], 0, strlen($attr[1]) - 1));
    9493                        if ($attr[1] > $size) {
     
    9998                }
    10099                if (isset($retSrc)) {
    101                     return $this->_url_to_absolute($retSrc);
    102                 }
    103             }
    104             //Else just return src
     100                    return Piio_Image_Optimization_File_Helper::url_to_absolute($retSrc);
     101                }
     102            }
     103            // Else just return src
    105104            preg_match('/\bsrc\W*=\W*[\'"](.*)?[\'"]/Uxis', $imgTag, $matches);
    106             return (isset($matches[1])) ? $this->_url_to_absolute($matches[1]) : null;
     105            return (isset($matches[1])) ? Piio_Image_Optimization_File_Helper::url_to_absolute($matches[1]) : null;
    107106        }
    108107
     
    110109        {
    111110            // Get consumption
    112             $consumption = $this->get_consumption();
     111            $consumption = $this->_check_consumption();
    113112
    114113            // Check for standard or adv optimization
    115114            $optimization = get_option('piio_imageopt_optimization');
    116             $use_data_piio = isset($optimization[0]) ? ($optimization[0] === "1") : true;
    117 
    118             // Change tags if adv optimization or consumption is not in danger
    119             $consumption_ok = $use_data_piio || ($consumption !== 'danger');
     115            $adv_optimization = isset($optimization[0]) ? ($optimization[0] === "1") : true;
     116
     117            // Replace tags if adv optimization (js will take care of it) or consumption is not in danger
     118            $replace_tags = $adv_optimization || ($consumption !== 'danger');
    120119
    121120            // Check if optimize for editors is set
     
    128127            $is_admin = is_admin();
    129128
    130             if ($consumption_ok && !$is_admin && !$editor) {
    131                 //Get optimization option and api key
     129            if ($replace_tags && !$is_admin && !$editor) {
     130                // Get api key
    132131                $api_key = get_option('piio_imageopt_api_key');
    133 
    134                 $HTMLContent = $this->_replace_img_tags($HTMLContent, $use_data_piio, $api_key);
    135 
     132                // Check if webP is enabled
     133                $enable_webp = get_option('piio_imageopt_enable_webp');
     134                $enable_webp = isset($enable_webp[0]) ? ($enable_webp[0] === "1") : true;
     135                // Check if browser accepts webP
     136                $client_accept_webp = strpos($_SERVER['HTTP_ACCEPT'], 'image/webp') !== false;
     137
     138                $HTMLContent = $this->_replace_img_tags($HTMLContent, $adv_optimization, $api_key, $enable_webp, $client_accept_webp);
     139
     140                // Check if we have to optimize background images
    136141                $optimize_bck = get_option('piio_imageopt_optimize_bck');
    137142                $optimize_bck = isset($optimize_bck[0]) ? ($optimize_bck[0] === "1") : true;
    138143
    139144                if ($optimize_bck) {
    140                     $HTMLContent = $this->_replace_bck_styles($HTMLContent, $use_data_piio, $api_key);
     145                    $HTMLContent = $this->_replace_bck_styles($HTMLContent, $adv_optimization, $api_key, $enable_webp, $client_accept_webp);
    141146                }
    142147            }
     
    178183        }
    179184
    180         public function get_consumption()
     185        private function _check_consumption()
    181186        {
    182187            $piio_consumption_last_check = get_option('piio_imageopt_consumption_last_check');
    183             $check = false;
     188            $retrieve = false;
    184189            $now = date("Y-m-d");
    185190
    186191            // If no option or more than one day, check again
    187192            if (!$piio_consumption_last_check) {
    188                 $check = true;
     193                $retrieve = true;
    189194            } else {
    190195                $diffInDays = intval($this->_date_difference($piio_consumption_last_check, $now), 10);
    191                 $check = ($diffInDays > 1);
    192             }
    193 
    194             if ($check) {
    195                 // Request Piio for consumption
    196                 $api_key = get_option('piio_imageopt_api_key');
    197                 if ($api_key) {
    198                     $url = "https://app.piio.co/consumptionStatus/" . $api_key;
    199                     $response = wp_remote_get($url);
    200                     if (!is_wp_error($response)) {
    201                         if (isset($response['body'])) {
    202                             $response = json_decode($response['body']);
    203                             update_option('piio_imageopt_consumption_last_check', $now);
    204                             if ($response->status == 200) {
    205                                 update_option('piio_imageopt_consumption_status', $response->message);
    206                             }
    207                         }
     196                $retrieve = $diffInDays > 1;
     197            }
     198
     199            if ($retrieve) {
     200                // Retrieve consumption from server
     201                $this->_retrieve_consumption();
     202            }
     203
     204            return get_option('piio_imageopt_consumption_status');
     205        }
     206
     207        private function _retrieve_consumption()
     208        {
     209            // Request Piio for consumption
     210            $api_key = get_option('piio_imageopt_api_key');
     211            if ($api_key) {
     212                $url = "https://app.piio.co/consumptionStatus/" . $api_key;
     213                $response = wp_remote_get($url);
     214                if (!is_wp_error($response) && isset($response['body'])) {
     215                    $response = json_decode($response['body']);
     216                    $now = date("Y-m-d");
     217                    update_option('piio_imageopt_consumption_last_check', $now);
     218                    if ($response->status == 200) {
     219                        update_option('piio_imageopt_consumption_status', $response->message);
    208220                    }
    209221                }
    210222            }
    211 
    212             return get_option('piio_imageopt_consumption_status');
    213223        }
    214224
     
    222232        }
    223233
    224         private function _replace_img_tags($HTMLContent, $use_data_piio, $api_key)
    225         {
    226             $placeholder_url = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8+f9vPQAJZAN2rlRQVAAAAABJRU5ErkJggg==";
    227             $matches = array();
    228             preg_match_all('/<img[\s\r\n]+.*?>/is', $HTMLContent, $matches);
     234        private function _replace_img_tags($HTMLContent, $adv_optimization, $api_key, $enable_webp, $client_accept_webp)
     235        {
     236            $placeholder = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
     237            $img_tags_matches = array();
     238            preg_match_all('/<img[\s\r\n]+.*?>/is', $HTMLContent, $img_tags_matches);
    229239
    230240            $search = array();
     
    233243            $std_opt_img_added = false;
    234244
    235             $i = 0;
    236             foreach ($matches[0] as $imgHTML) {
    237                 // don't to the replacement if the image is a data-uri or has class piio-skip
     245            foreach ($img_tags_matches[0] as $imgHTML) {
     246                // Get largest image src
    238247                $src = $this->get_largest_image_src($imgHTML);
    239248
     249                // Don't to the replacement if the image is a data-uri or has class piio-skip
    240250                if (!preg_match("/data:image/is", $src) && !preg_match("/class=(['\"]|(['\"][^'\"]*)\s)piio-skip(['\"]|\s([^'\"]*)['\"])/is", $imgHTML)) {
    241                     $i++;
    242 
    243                     // get largest image src
    244 
    245                     $replaceHTML = '';
    246 
    247                     if ($use_data_piio) {
    248                         // advanced optimization enabled
    249 
    250                         // replace the src and add the data-piio attribute
    251                         $replaceHTML = preg_replace('/<img(.*?)src=(["\'])(.*?)["\']/is', '<img$1src=$2' . $placeholder_url . '$2 data-piio=$2' . urldecode($src) . "$2", $imgHTML);
    252                         // remove srcset and sizes attributes
    253                         $replaceHTML = preg_replace('/<img(.*?)srcset=["\'].*?["\']/is', '<img$1', $replaceHTML);
    254                         $replaceHTML = preg_replace('/<img(.*?)sizes=["\'].*?["\']/is', '<img$1', $replaceHTML);
     251                    if ($adv_optimization) {
     252                        // Advanced optimization enabled
     253                        $replaceHTML = $this->_advanced_mode($imgHTML, $src, $placeholder);
    255254                    } else {
    256                         // standard optimization enabled
    257 
    258                         $enable_webp = get_option('piio_imageopt_enable_webp');
    259                         $enable_webp = isset($enable_webp[0]) ? ($enable_webp[0] === "1") : true;
    260 
    261                         $params = '';
    262                         //Check if client is using Chrome
    263                         if ($enable_webp && preg_match('/(Chrome)\//i', $_SERVER['HTTP_USER_AGENT']) && !preg_match('/(Aviator|ChromePlus|coc_|Dragon|Edge|Flock|Iron|Kinza|Maxthon|MxNitro|Nichrome|OPR|Perk|Rockmelt|Seznam|Sleipnir|Spark|UBrowser|Vivaldi|WebExplorer|YaBrowser)/i', $_SERVER['HTTP_USER_AGENT'])) {
    264                             $params .= 'wp,1';
    265                         }
    266 
    267                         // remove srcset and sizes attributes as we are adding our own
    268                         $replaceHTML = preg_replace('/<img(.*?)srcset=["\'].*?["\']/is', '<img$1', $imgHTML);
    269                         $replaceHTML = preg_replace('/<img(.*?)sizes=["\'].*?["\']/is', '<img$1', $replaceHTML);
    270 
    271                         $srcAttr = urlencode($src);
    272 
    273                         $breakpoints = array("576", "768", "992", "1200");
    274                         $srcset_values = array();
    275                         foreach ($breakpoints as $width) {
    276                             $local_params = 'vw,' . $width . (($params != '') ? ',' . $params : '');
    277                             array_push($srcset_values, 'https://pcdn.piiojs.com/i/' . $api_key . '/' . $local_params . '/' . $srcAttr . ' ' . $width . 'w');
    278                         }
    279                         // replace src with largest image and add srcset
    280                         $replaceHTML = preg_replace('/<img(.*?)src=(["\'])(.*?)["\']/is', '<img$1src=$2' . 'https://pcdn.piiojs.com/i/' . $api_key . (($params != '') ? '/' . $params : '') . '/' . $srcAttr . '$2 srcset=$2' . implode(', ', $srcset_values) . '$2', $replaceHTML);
    281 
    282                         // add img with data-piio to log user data for consumption
     255                        // Standard optimization enabled
     256                        $replaceHTML = $this->_standard_mode($imgHTML, $src, $api_key, $enable_webp, $client_accept_webp);
     257
     258                        // Add img with data-piio to log user data for consumption
    283259                        if (!$std_opt_img_added) {
    284                             $body_matches = array();
    285                             if (preg_match('/<body.*?>/is', $HTMLContent, $body_matches, PREG_OFFSET_CAPTURE) > 0) {
    286                                 // get <body start position
    287                                 // body_matches[0][0] contains string, body_matches[0][1] contains string index
    288                                 $body_end_pos = $body_matches[0][1] + strlen($body_matches[0][0]);
    289                                 $HTMLContent = substr_replace($HTMLContent, $this->_get_transparent_svg_with_piio(), $body_end_pos, 0);
    290                             };
     260                            $HTMLContent = $this->_add_data_piio_img($HTMLContent);
    291261                            $std_opt_img_added = true;
    292262                        }
     
    304274        }
    305275
    306         private function _replace_bck_styles($HTMLContent, $use_data_piio, $api_key)
     276        private function _replace_bck_styles($HTMLContent, $adv_optimization, $api_key, $enable_webp, $client_accept_webp)
    307277        {
    308278            $matches = array();
     
    312282            $replace = array();
    313283
    314             $i = 0;
     284            $params = "";
     285            // Set wp param is webP is enabled
     286            if ($enable_webp && $client_accept_webp) {
     287                $params .= "wp,1";
     288            }
     289            $callback = new Piio_Image_Optimization_Callbacks($api_key, $params);
     290
    315291            foreach ($matches[0] as $bckHTML) {
    316                 // don't to the replacement if the image is a data-uri or has class piio-skip
     292                // Don't to the replacement if the image is a data-uri or has class piio-skip
    317293                if (!preg_match("/url\(['\"]data:image/is", $bckHTML) && !preg_match("/class=(['\"]|(['\"][^'\"]*)\s)piio-skip(['\"]|\s([^'\"]*)['\"])/is", $bckHTML)) {
    318                     $i++;
    319 
    320294                    $replaceHTML = '';
    321295
    322                     if ($use_data_piio) {
    323                         // replace the background-image attribute from style and add the data-piio-bck attribute
    324                         $replaceHTML = preg_replace("/(\sstyle=['\"][^>]*?)(background-image:.*?url\((\s*.*?\s*)\));?(.*?['\"])/is", '$1$4 data-piio-bck=' . urldecode("$3"), $bckHTML);
    325                         $replaceHTML = preg_replace("/(\sstyle=['\"][^>]*?background:.*?)(url\((\s*.*?\s*)\));?(.*?['\"])/is", '$1$4 data-piio-bck=' . urldecode("$3"), $replaceHTML);
     296                    if ($adv_optimization) {
     297                        // Replace the background-image attribute from style and add the data-piio-bck attribute
     298                        $replaceHTML = preg_replace("/(\sstyle=['\"][^>]*?)(background-image:.*?url\((\s*.*?\s*)\));?(.*?['\"])/is", '$1$4 data-piio-bck=$3', $bckHTML);
     299                        $replaceHTML = preg_replace("/(\sstyle=['\"][^>]*?background:.*?)(url\((\s*.*?\s*)\));?(.*?['\"])/is", '$1$4 data-piio-bck=$3', $replaceHTML);
    326300                    } else {
    327                         $enable_webp = get_option('piio_imageopt_enable_webp');
    328                         $enable_webp = isset($enable_webp[0]) ? ($enable_webp[0] === "1") : true;
    329 
    330                         $params = "";
    331                         //Check if client is using Chrome
    332                         if ($enable_webp && preg_match('/(Chrome)\//i', $_SERVER['HTTP_USER_AGENT']) && !preg_match('/(Aviator|ChromePlus|coc_|Dragon|Edge|Flock|Iron|Kinza|Maxthon|MxNitro|Nichrome|OPR|Perk|Rockmelt|Seznam|Sleipnir|Spark|UBrowser|Vivaldi|WebExplorer|YaBrowser)/i', $_SERVER['HTTP_USER_AGENT'])) {
    333                             $params .= "wp,1";
    334                         }
    335 
    336                         $callback = new Piio_Image_Optimization_Callbacks($api_key, $params);
    337 
     301                        // Using callback because of replace length
    338302                        $replaceHTML = preg_replace_callback("/(\sstyle=['\"][^>]*?)(background-image:.*?url\(['\"](\s*.*?\s*)['\"]\));?(.*?['\"])/is", array($callback, 'callback_background_image'), $bckHTML);
    339 
    340303                        $replaceHTML = preg_replace_callback("/(\sstyle=['\"][^>]*?background:.*?url\(['\"])(\s*.*?\s*)(['\"]\);?.*?['\"])/is", array($callback, 'callback_background'), $replaceHTML);
    341304                    }
     
    354317        private function _get_transparent_svg_with_piio()
    355318        {
    356             return "<img src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8+f9vPQAJZAN2rlRQVAAAAABJRU5ErkJggg==' data-piio='" . plugin_dir_url(__FILE__) . 'images/transparent.svg' . "' style='width:1px !important;height:1px !important;position:absolute !important;top:0 !important;left:-1px !important'>";
    357         }
    358 
    359         private function _url_to_absolute($relativeUrl)
    360         {
    361             $baseUrl = get_site_url();
    362             // If relative URL has a scheme, clean path and return.
    363             $r = parse_url($relativeUrl);
    364             if ($r === false) {
    365                 return false;
    366             }
    367             if (!empty($r['scheme'])) {
    368                 if (!empty($r['path']) && $r['path'][0] == '/') {
    369                     $r['path'] = $this->_url_remove_dot_segments($r['path']);
    370                 }
    371                 return $this->_join_url($r);
    372             }
    373 
    374             // Make sure the base URL is absolute.
    375             $b = parse_url($baseUrl);
    376             if ($b === false || empty($b['scheme']) || empty($b['host'])) {
    377                 return false;
    378             }
    379             $r['scheme'] = $b['scheme'];
    380 
    381             // If relative URL has an authority, clean path and return.
    382             if (isset($r['host'])) {
    383                 if (!empty($r['path'])) {
    384                     $r['path'] = $this->_url_remove_dot_segments($r['path']);
    385                 }
    386                 return $this->_join_url($r);
    387             }
    388             unset($r['port']);
    389             unset($r['user']);
    390             unset($r['pass']);
    391 
    392             // Copy base authority.
    393             $r['host'] = $b['host'];
    394             if (isset($b['port'])) {
    395                 $r['port'] = $b['port'];
    396             }
    397             if (isset($b['user'])) {
    398                 $r['user'] = $b['user'];
    399             }
    400             if (isset($b['pass'])) {
    401                 $r['pass'] = $b['pass'];
    402             }
    403 
    404             // If relative URL has no path, use base path
    405             if (empty($r['path'])) {
    406                 if (!empty($b['path'])) {
    407                     $r['path'] = $b['path'];
    408                 }
    409                 if (!isset($r['query']) && isset($b['query'])) {
    410                     $r['query'] = $b['query'];
    411                 }
    412                 return $this->_join_url($r);
    413             }
    414 
    415             // If relative URL path doesn't start with /, merge with base path
    416             if ($r['path'][0] != '/') {
    417                 $base = mb_strrchr($b['path'], '/', true, 'UTF-8');
    418                 if ($base === false) {
    419                     $base = '';
    420                 }
    421                 $r['path'] = $base . '/' . $r['path'];
    422             }
    423             $r['path'] = $this->_url_remove_dot_segments($r['path']);
    424             return $this->_join_url($r);
    425         }
    426 
    427         private function _join_url($parts, $encode = true)
    428         {
    429             if ($encode) {
    430                 if (isset($parts['user'])) {
    431                     $parts['user'] = rawurlencode($parts['user']);
    432                 }
    433                 if (isset($parts['pass'])) {
    434                     $parts['pass'] = rawurlencode($parts['pass']);
    435                 }
    436                 if (isset($parts['host']) && !preg_match('!^(\[[\da-f.:]+\]])|([\da-f.:]+)$!ui', $parts['host'])) {
    437                     $parts['host'] = rawurlencode($parts['host']);
    438                 }
    439                 if (!empty($parts['path'])) {
    440                     $parts['path'] = preg_replace('!%2F!ui', '/', rawurlencode($parts['path']));
    441                 }
    442                 if (isset($parts['query'])) {
    443                     $parts['query'] = rawurlencode($parts['query']);
    444                 }
    445                 if (isset($parts['fragment'])) {
    446                     $parts['fragment'] = rawurlencode($parts['fragment']);
    447                 }
    448             }
    449 
    450             $url = '';
    451             if (!empty($parts['scheme'])) {
    452                 $url .= $parts['scheme'] . ':';
    453             }
    454             if (isset($parts['host'])) {
    455                 $url .= '//';
    456                 if (isset($parts['user'])) {
    457                     $url .= $parts['user'];
    458                     if (isset($parts['pass'])) {
    459                         $url .= ':' . $parts['pass'];
    460                     }
    461                     $url .= '@';
    462                 }
    463                 if (preg_match('!^[\da-f]*:[\da-f.:]+$!ui', $parts['host'])) {
    464                     $url .= '[' . $parts['host'] . ']'; // IPv6
    465                 } else {
    466                     $url .= $parts['host'];             // IPv4 or name
    467                 }
    468                 if (isset($parts['port'])) {
    469                     $url .= ':' . $parts['port'];
    470                 }
    471                 if (!empty($parts['path']) && $parts['path'][0] != '/') {
    472                     $url .= '/';
    473                 }
    474             }
    475             if (!empty($parts['path'])) {
    476                 $url .= $parts['path'];
    477             }
    478             if (isset($parts['query'])) {
    479                 $url .= '?' . $parts['query'];
    480             }
    481             if (isset($parts['fragment'])) {
    482                 $url .= '#' . $parts['fragment'];
    483             }
    484             return $url;
    485         }
    486 
    487         private function _url_remove_dot_segments($path)
    488         {
    489             // multi-byte character explode
    490             $inSegs = preg_split('!/!u', $path);
    491             $outSegs = array( );
    492             foreach ($inSegs as $seg) {
    493                 if ($seg == '' || $seg == '.') {
    494                     continue;
    495                 }
    496                 if ($seg == '..') {
    497                     array_pop($outSegs);
    498                 } else {
    499                     array_push($outSegs, $seg);
    500                 }
    501             }
    502             $outPath = implode('/', $outSegs);
    503             if ($path[0] == '/') {
    504                 $outPath = '/' . $outPath;
    505             }
    506             // compare last multi-byte character against '/'
    507             if ($outPath != '/' && (mb_strlen($path)-1) == mb_strrpos($path, '/', 'UTF-8')) {
    508                 $outPath .= '/';
    509             }
    510             return $outPath;
     319            return "<img src='data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7' data-piio='" . plugin_dir_url(__FILE__) . 'images/transparent.svg' . "' style='width:1px !important;height:1px !important;position:absolute !important;top:0 !important;left:-1px !important'>";
     320        }
     321
     322        private function _advanced_mode($imgHTML, $src, $placeholder)
     323        {
     324            // Remove srcset and sizes attributes
     325            $replaceHTML = preg_replace('/<img(.*?)srcset=["\'].*?["\']/is', '<img$1', $imgHTML);
     326            $replaceHTML = preg_replace('/<img(.*?)sizes=["\'].*?["\']/is', '<img$1', $replaceHTML);
     327
     328            // Replace the src with the data-piio attribute
     329            $replaceHTML = preg_replace('/<img(.*?)src=(["\']).*?["\']/is', '<img$1src=$2' . $placeholder . '$2 data-piio=$2' . $src . "$2", $replaceHTML);
     330
     331            return $replaceHTML;
     332        }
     333
     334        private function _standard_mode($imgHTML, $src, $api_key, $enable_webp, $client_accept_webp)
     335        {
     336            $srcAttr = urlencode($src);
     337
     338            // Remove srcset and sizes attributes as we are adding our own
     339            $replaceHTML = preg_replace('/<img(.*?)srcset=["\'].*?["\']/is', '<img$1', $imgHTML);
     340            $replaceHTML = preg_replace('/<img(.*?)sizes=["\'].*?["\']/is', '<img$1', $replaceHTML);
     341
     342            // Check if image is an svg
     343            if (pathinfo($srcAttr, PATHINFO_EXTENSION) == 'svg') {
     344                $replaceHTML = preg_replace('/<img(.*?)src=(["\']).*?["\']/is', '<img$1src=$2' . 'https://pcdn.piiojs.com/i/' . $api_key . '/' . $srcAttr . "$2", $replaceHTML);
     345            } else {
     346                $params = '';
     347                // Set wp param is webP is enabled
     348                if ($enable_webp && $client_accept_webp) {
     349                    $params .= 'wp,1,';
     350                }
     351
     352                $breakpoints = array("576", "768", "992", "1200");
     353                $srcset_values = array();
     354                foreach ($breakpoints as $width) {
     355                    $local_params = $params . 'vw,' . $width;
     356                    array_push($srcset_values, 'https://pcdn.piiojs.com/i/' . $api_key . '/' . $local_params . '/' . $srcAttr . ' ' . $width . 'w');
     357                }
     358                // Replace src with largest image and add srcset
     359                $replaceHTML = preg_replace('/<img(.*?)src=(["\']).*?["\']/is', '<img$1src=$2' . 'https://pcdn.piiojs.com/i/' . $api_key . (($params != '') ? '/' . $params : '') . '/' . $srcAttr . '$2 srcset=$2' . implode(', ', $srcset_values) . '$2', $replaceHTML);
     360            }
     361
     362            return $replaceHTML;
     363        }
     364
     365        private function _add_data_piio_img($HTMLContent)
     366        {
     367            $body_matches = array();
     368            if (preg_match('/<body.*?>/is', $HTMLContent, $body_matches, PREG_OFFSET_CAPTURE) > 0) {
     369                // Get <body start position
     370                // Body_matches[0][0] contains string, body_matches[0][1] contains string index
     371                $body_end_pos = $body_matches[0][1] + strlen($body_matches[0][0]);
     372                $HTMLContent = substr_replace($HTMLContent, $this->_get_transparent_svg_with_piio(), $body_end_pos, 0);
     373            };
     374            return $HTMLContent;
    511375        }
    512376    }
  • piio-image-optimization/trunk/readme.txt

    r2008456 r2012339  
    66Requires PHP: 5.3.0
    77Tested up to: 5.0
    8 Stable tag: 0.9.15
     8Stable tag: 0.9.16
    99License: GPLv2 or later
    1010License URI: http://www.gnu.org/licenses/gpl-2.0.html
     
    125125
    126126== Changelog ==
     127= 0.9.16 =
     128* Check consumption status manually
    127129= 0.9.15 =
    128130* Improved compatibility with cache plugins
Note: See TracChangeset for help on using the changeset viewer.