Plugin Directory

Changeset 2664756


Ignore:
Timestamp:
01/25/2022 04:45:53 PM (4 years ago)
Author:
speedien
Message:

v1.1.0

Location:
speedien
Files:
6 added
5 deleted
4 edited
1 copied

Legend:

Unmodified
Added
Removed
  • speedien/tags/1.1.0/readme.txt

    r2503658 r2664756  
    1 === Core Web Vitals Booster by Speedien ===
    2 Contributors: speedien
     1=== Core Web Vitals Booster ===
     2Contributors: speedien, nestify
    33Tags: pagespeed, cache, webperf, core web vitals, vitals
    4 Requires at least: 4.5
    5 Tested up to: 5.7
     4Requires at least: 4.6
     5Tested up to: 5.8
    66Requires PHP: 5.6
    7 Stable tag: 1.0.1
     7Stable tag: 1.1.0
    88License: GPLv2 or later
    99License URI: https://www.gnu.org/licenses/gpl-2.0.html
    1010
    11 Core web vitals booster by Speedien. This plugin will link your Speedien.com account and your site to improve page speed.
     11Core web vitals booster for Nestify.io. This plugin will optimize pagespeed of your sites hosted on Nestify.
    1212
    1313== Description ==
    14 **This plugin requires an active subscription from Speedien.com to function properly. You can signup for a free trial subscription at My.speedien.com**
     14**This plugin only supports WordPress sites hosted on https://nestify.io. You can signup for a free trial subscription at https://nestify.io**
    1515
    1616Speedien optmizes your site for best performance on desktop and mobile devices automatically. No coding required. We start by prioritizing resources needed for above-the-fold content and deferring everything else. This helps improve core web vitals metrics automatically and help with search engine rankings.
    17 
    18 Speedien is a cloud based service that performs the heavy lifting on remote servers. This approach ensures that your hosting performance plays a very little role in overall site speed.
    1917
    2018This plugin enables a high speed global CDN that automatically optimizes site's static assets, images, and videos. CDN also converts images to WebP format to reduce the file size. Images are automatically resized according to visitor's screen size.
     
    6260All paid subscriptions have access to 24x7 priority support with 1 hour response time or less
    6361
     62## Known incompatible plugins
     63
     64This plugin contains functionality that overlaps with the following plugins. It is recommended that you deactivate these plugins when using core web vitals booster.
     65
     66* Autoptimize
     67* Breeze
     68* Cloudflare
     69* Comet Cache by WP Sharks
     70* EWWW Image Optimizer
     71* Hummingbird
     72* Imagify
     73* JetPack
     74* Lazy Load
     75* Litespeed Cache
     76* Nitropack
     77* PageSpeed Ninja
     78* Perfmatters
     79* PhastPress
     80* SG Optimizer
     81* ShortPixel
     82* Smush
     83* Swift Performance
     84* W3 Total Cache
     85* WP Cloudflare
     86* WP Fastest Cache
     87* WP Optimize
     88* WP Rocket
     89* WP Super Cache
     90
    6491## 3rd Party Services Used By The Speedien Plugin
    6592
     
    6996* Speedien Terms of Service - [https://speedien.com/terms-of-service/](https://speedien.com/terms-of-service/)
    7097* Speedien Privacy Policy - [https://speedien.com/privacy-policy/](https://speedien.com/privacy-policy/)
     98
     99Speedien uses Nestify.io for WordPress hosting and optimization services. For more information about Nestify, please visit:
     100
     101* Nestify website - [https://nestify.io](https://nestify.io/)
     102* Nestify Terms of Service - [https://nestify.io/terms-of-service/](https://nestify.io/terms-of-service/)
     103* Nestify Privacy Policy - [https://nestify.io/privacy-policy/](https://nestify.io/privacy-policy/)
    71104
    72105Speedien uses Bunny CDN for some of our optimization functionality. For more information about Bunny CDN, please visit:
     
    102135
    103136== Screenshots ==
    104 1. Optimization settings
    105 2. Plugin options
    106 3. Core web vitals report
     1371. Plugin options
     1382. Core web vitals report
    107139
    108140== Changelog ==
     141
     142= 1.1.0 - 25 Jan, 2022 =
     143- Major redesign to replace existing cache-preload model with real-time optimizations.
     144- Added pagespeed optimization settings panel in wp-admin.
     145
     146= 1.0.8 - 4 Aug, 2021 =
     147- Improved cache purge error handling
     148- Added cache bypass mechanism for Divi page builder
     149
     150= 1.0.7 - 30 Jun, 2021 =
     151- Added support for defining credentials through wp-config.php
     152
     153= 1.0.6 - 22 Jun, 2021 =
     154- Enabled 'always-on' CDN for all pages
     155
     156= 1.0.5 - 19 Jun, 2021 =
     157- Improved 404 and error handling
     158- Minor bug fixes
     159
     160= 1.0.4 - 14 Jun, 2021 =
     161- Improved javascript optimization
     162- Improved cache handling
     163- Added cache bypass mechanism using cookies or query parameters
     164
     165= 1.0.3 - 19 Apr, 2021 =
     166- Added support for preloading cache via Speedien console
     167- Improved error handling for empty cache directory
     168
     169= 1.0.2 - 30 Mar, 2021 =
     170- Improved cache preloading
     171- Updated deactivation handling
    109172
    110173= 1.0.1 - 25 Mar, 2021 =
  • speedien/tags/1.1.0/speedien.php

    r2504162 r2664756  
    11<?php
    22/**
    3  * Plugin Name:     Core Web Vitals Booster by Speedien
     3 * Plugin Name:     Core Web Vitals Booster
    44 * Plugin URI:      https://speedien.com
    5  * Description:     Plugin to auto-purge speedien.com cache.
     5 * Description:     Plugin to help with core web vitals metrics and page speed.
    66 * Author:          Speedien Team
    77 * Text Domain:     speedien
    88 * Domain Path:     /
    9  * Version:         1.0.1
     9 * Version:         1.1.0
    1010 */
    1111
     
    1717define('SPEEDIEN_API_URL', 'https://my.speedien.com');
    1818
     19require_once 'speedien_config.php';
    1920require_once 'speedien_ui.php';
    20 require_once 'speedien_admin_bar.php';
    21 require_once 'speedien_admin_notice.php';
    2221require_once 'speedien_cache.php';
    23 require_once 'speedien_purge_hooks.php';
     22
     23register_activation_hook( __FILE__, 'speedien_cache_init' );
     24
     25/**
     26 * Deactivation hook.
     27 */
     28function speedien_deactivate() {
     29    unlink(WP_CONTENT_DIR . '/advanced-cache.php');
     30    $wp_config = file_get_contents($wp_config_file);
     31    $wp_cache = '/define\([\'\"]WP_CACHE[\'\"].*/';
     32    $wp_config = preg_replace($wp_cache, '', $wp_config);
     33    file_put_contents($wp_config_file, $wp_config);
     34}
     35register_deactivation_hook( __FILE__, 'speedien_deactivate' );
  • speedien/tags/1.1.0/speedien_cache.php

    r2503641 r2664756  
    55    $bypass_cache = 0;
    66
    7     $speedien_cache_exclusions = array('wp-login.php','wp-cron.php','wc-api','wp-json','my-account','cart','checkout','amp','feed','xmlrpc');
     7    $speedien_cache_exclusions = array('wp-login.php','wp-cron.php','wp-admin','wc-api','wp-json','my-account','cart','checkout','amp','feed','page','tag','search','xmlrpc','.xml','disable');
    88
    99    foreach($speedien_cache_exclusions as $slug)
    1010    {
    11         if(strpos($_SERVER['REQUEST_URI'], $slug) !== false)
     11        if(strpos(strtolower($_SERVER['REQUEST_URI']), $slug) !== false)
    1212        {
    1313            $bypass_cache = 1;
     
    1818        $bypass_cache = 1;
    1919    }
     20 
     21    if ( is_404() ) {
     22        $bypass_cache = 1;
     23    }
    2024
    2125    if (!isset($_SERVER['REQUEST_METHOD']) || !in_array($_SERVER['REQUEST_METHOD'], ['HEAD', 'GET'])) {
     
    2327    }
    2428
     29    if(!empty($_GET['s']) || !empty($_GET['no-optimization'])) {
     30        $bypass_cache = 1;
     31    }
     32
    2533    if(!empty($_COOKIE))
    2634    {
    27         $cookielist = '/(wordpress_[a-f0-9]+|comment_author|wp-postpass|wordpress_no_cache|wordpress_logged_in|woocommerce_cart_hash|woocommerce_items_in_cart|woocommerce_recently_viewed|edd_items_in_cart)/';
     35        if(!empty($_COOKIE['wordpress_logged_in_1']))
     36        {
     37            if($_COOKIE['wordpress_logged_in_1'] !== 'speedien')
     38            {
     39                $bypass_cache = 1;
     40            }
     41        }
     42        $cookielist = '/(wordpress_[a-f0-9]+|comment_author|wp-postpass|wordpress_no_cache|woocommerce_cart_hash|woocommerce_items_in_cart|woocommerce_recently_viewed|edd_items_in_cart)/';
    2843        $cookies = sanitize_text_field(implode('', array_keys($_COOKIE)));
    2944        if (preg_match($cookielist, $cookies)) {
    3045            $bypass_cache = 1;
     46        }
     47    }
     48
     49    $options = get_option('speedien_options');
     50    if(!empty($options['speedien_field_pagelist']))
     51    {
     52        $page_exclusions = explode(PHP_EOL, $options['speedien_field_pagelist']);
     53        foreach($page_exclusions as $exclusion)
     54        {
     55            if(strpos(strtolower($_SERVER['REQUEST_URI']), trim($exclusion)) !== false)
     56            {
     57                $bypass_cache = 1;
     58            }
    3159        }
    3260    }
     
    4068    if(!$bypass_cache)
    4169    {
    42         ob_start("speedien_submit_to_cloud");
    43     }
    44 }
    45 
    46 function speedien_submit_to_cloud($buffer)
     70        ob_start("speedien_cdn_rewrite");
     71    }
     72}
     73
     74function speedien_cdn_rewrite($buffer)
    4775{
     76    $REPLACEMENTS = [];
     77        $searchOffset = 0;
     78        while (preg_match('/<script\b[^>]*?>/is', $buffer, $matches, PREG_OFFSET_CAPTURE, $searchOffset)) {
     79            $offset = $matches[0][1];
     80            $searchOffset = $offset + 1;
     81            if (preg_match('/<\/\s*script>/is', $buffer, $endMatches, PREG_OFFSET_CAPTURE, $matches[0][1])) {
     82                $len = $endMatches[0][1] - $matches[0][1] + strlen($endMatches[0][0]);
     83                $everything = substr($buffer, $matches[0][1], $len);
     84                $tag = $matches[0][0];
     85                $closingTag = $endMatches[0][0];
     86
     87                $hasSrc = preg_match('/\s+src=/i', $tag);
     88                $hasType = preg_match('/\s+type=/i', $tag);
     89                $shouldReplace = !$hasType || preg_match('/\s+type=([\'"])((application|text)\/(javascript|ecmascript|html|template)|module)\1/i', $tag);
     90                $noOptimize = preg_match('/data-wpspdn-nooptimize="true"/i', $tag);
     91                if ($shouldReplace && !$hasSrc && !$noOptimize) {
     92                    // inline script
     93                    $content = substr($buffer, $matches[0][1] + strlen($matches[0][0]), $endMatches[0][1] - $matches[0][1] - strlen($matches[0][0]));
     94                    if (apply_filters('wpspdn_exclude', false, $content)) {
     95                        $replacement = preg_replace('/^<script\b/i', '<script data-wpspdn-nooptimize="true"', $everything);
     96                        $buffer = substr_replace($buffer, $replacement, $offset, $len);
     97                        continue;
     98                    }
     99                    $replacement = $tag . "wpspdn[" . count($REPLACEMENTS) . "]wpspdn" . $closingTag;
     100                    $REPLACEMENTS[] = $content;
     101                    $buffer = substr_replace($buffer, $replacement, $offset, $len);
     102                    continue;
     103                }
     104            }
     105        }
     106
     107        $buffer = preg_replace_callback('/<script\b[^>]*?>/i', function ($matches) {
     108            list($tag) = $matches;
     109
     110            $EXTRA = constant('wpspdn_EXTRA_ATTRS') ?: '';
     111
     112            $result = $tag;
     113            if (!preg_match('/\s+data-src=/i', $result)
     114                && !preg_match('/data-wpspdn-nooptimize="true"/i', $result)
     115                && !preg_match('/data-rocketlazyloadscript=/i', $result)) {
     116
     117                $src = preg_match('/\s+src=([\'"])(.*?)\1/i', $result, $matches)
     118                    ? $matches[2]
     119                    : null;
     120                if (!$src) {
     121                    // trying to detect src without quotes
     122                    $src = preg_match('/\s+src=([\/\w\-\.\~\:\[\]\@\!\$\?\&\#\(\)\*\+\,\;\=\%]+)/i', $result, $matches)
     123                        ? $matches[1]
     124                        : null;
     125                }
     126                $hasType = preg_match('/\s+type=/i', $result);
     127                $isJavascript = !$hasType
     128                    || preg_match('/\s+type=([\'"])((application|text)\/(javascript|ecmascript)|module)\1/i', $result)
     129                    || preg_match('/\s+type=((application|text)\/(javascript|ecmascript)|module)/i', $result);
     130                if ($isJavascript) {
     131                    if ($src) {
     132                        if (apply_filters('wpspdn_exclude', false, $src)) {
     133                            return $result;
     134                        }
     135                        $result = preg_replace('/\s+src=/i', " data-src=", $result);
     136                        $result = preg_replace('/\s+(async|defer)\b/i', " data-\$1", $result);
     137                    }
     138                    if ($hasType) {
     139                        $result = preg_replace('/\s+type=([\'"])module\1/i', " type=\"javascript/blocked\" data-wpspdn-module ", $result);
     140                        $result = preg_replace('/\s+type=module\b/i', " type=\"javascript/blocked\" data-wpspdn-module ", $result);
     141                        $result = preg_replace('/\s+type=([\'"])(application|text)\/(javascript|ecmascript)\1/i', " type=\"javascript/blocked\"", $result);
     142                        $result = preg_replace('/\s+type=(application|text)\/(javascript|ecmascript)\b/i', " type=\"javascript/blocked\"", $result);
     143                    } else {
     144                        $result = preg_replace('/<script/i', "<script type=\"javascript/blocked\"", $result);
     145                    }
     146                    $result = preg_replace('/<script/i', "<script ${EXTRA} data-wpspdn-after=\"REORDER\"", $result);
     147                }
     148            }
     149            return preg_replace('/\s*data-wpspdn-nooptimize="true"/i', '', $result);
     150        }, $buffer);
     151
     152        $buffer = preg_replace_callback('/wpspdn\[(\d+)\]wpspdn/', function ($matches) use (&$REPLACEMENTS) {
     153            return $REPLACEMENTS[(int)$matches[1]];
     154        }, $buffer);
     155
     156        $buffer = str_replace('</head>','<script data-cfasync="false">var _wpspdn={"rdelay":86400000,"elementor-animations":true,"elementor-pp":true,"v":"2.3.10"};if(navigator.userAgent.match(/MSIE|Internet Explorer/i)||navigator.userAgent.match(/Trident\/7\..*?rv:11/i)){var href=document.location.href;if(!href.match(/[?&]wpspdndisable/)){if(href.indexOf("?")==-1){if(href.indexOf("#")==-1){document.location.href=href+"?wpspdndisable=1"}else{document.location.href=href.replace("#","?wpspdndisable=1#")}}else{if(href.indexOf("#")==-1){document.location.href=href+"&wpspdndisable=1"}else{document.location.href=href.replace("#","&wpspdndisable=1#")}}}}</script><script data-cfasync="false">!function(t){var e={};function n(r){if(e[r])return e[r].exports;var o=e[r]={i:r,l:!1,exports:{}};return t[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=t,n.c=e,n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:r})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var o in t)n.d(r,o,function(e){return t[e]}.bind(null,o));return r},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="/",n(n.s=0)}([function(t,e,n){t.exports=n(1)},function(t,e,n){"use strict";n.r(e);var r=new(function(){function t(){this.l=[]}var e=t.prototype;return e.emit=function(t,e){void 0===e&&(e=null),this.l[t]&&this.l[t].forEach((function(t){return t(e)}))},e.on=function(t,e){var n;(n=this.l)[t]||(n[t]=[]),this.l[t].push(e)},e.off=function(t,e){this.l[t]=(this.l[t]||[]).filter((function(t){return t!==e}))},t}()),o=new Date,i=document,a=function(){function t(){this.known=[]}var e=t.prototype;return e.init=function(){var t,e=this,n=!1,o=function(t){if(!n&&t&&t.fn&&!t.__wpspdn){var r=function(e){return i.addEventListener("DOMContentLoaded",(function(n){e.bind(i)(t,n)})),this};e.known.push([t,t.fn.ready,t.fn.init.prototype.ready]),t.fn.ready=r,t.fn.init.prototype.ready=r,t.__wpspdn=!0}return t};window.jQuery&&(t=o(window.jQuery)),Object.defineProperty(window,"jQuery",{get:function(){return t},set:function(e){return t=o(e)}}),r.on("l",(function(){return n=!0}))},e.unmock=function(){this.known.forEach((function(t){var e=t[0],n=t[1],r=t[2];e.fn.ready=n,e.fn.init.prototype.ready=r}))},t}(),c={};!function(t,e){try{var n=Object.defineProperty({},e,{get:function(){c[e]=!0}});t.addEventListener(e,null,n),t.removeEventListener(e,null,n)}catch(t){}}(window,"passive");var u=c,f=window,d=document,s=["mouseover","keydown","touchmove","touchend","wheel"],l=["mouseover","mouseout","touchstart","touchmove","touchend","click"],p="data-wpspdn-",v=function(){function t(){}return t.prototype.init=function(t){var e=!1,n=!1,o=function t(o){e||(e=!0,s.forEach((function(e){return d.body.removeEventListener(e,t,u)})),clearTimeout(n),location.href.match(/wpspdnnopreload/)||r.emit("pre"),r.emit("fi"))},i=function(t){var e=new MouseEvent("click",{view:t.view,bubbles:!0,cancelable:!0});return Object.defineProperty(e,"target",{writable:!1,value:t.target}),e};t<1e4&&r.on("i",(function(){e||(n=setTimeout(o,t))}));var a=[],c=function(t){t.target&&"dispatchEvent"in t.target&&("click"===t.type?(t.preventDefault(),t.stopPropagation(),a.push(i(t))):"touchmove"!==t.type&&a.push(t),t.target.setAttribute(p+t.type,!0))};r.on("l",(function(){var t;for(l.forEach((function(t){return f.removeEventListener(t,c)}));t=a.shift();){var e=t.target;e.getAttribute(p+"touchstart")&&e.getAttribute(p+"touchend")&&!e.getAttribute(p+"click")?(e.getAttribute(p+"touchmove")||(e.removeAttribute(p+"touchmove"),a.push(i(t))),e.removeAttribute(p+"touchstart"),e.removeAttribute(p+"touchend")):e.removeAttribute(p+t.type),e.dispatchEvent(t)}}));d.addEventListener("DOMContentLoaded",(function t(){s.forEach((function(t){return d.body.addEventListener(t,o,u)})),l.forEach((function(t){return f.addEventListener(t,c)})),d.removeEventListener("DOMContentLoaded",t)}))},t}(),m=document,h=m.createElement("span");h.setAttribute("id","elementor-device-mode"),h.setAttribute("class","elementor-screen-only");var y=window,b=document,g=b.documentElement,w=function(t){return t.getAttribute("class")||""},E=function(t,e){return t.setAttribute("class",e)},L=function(){window.addEventListener("load",(function(){var t=(m.body.appendChild(h),getComputedStyle(h,":after").content.replace(/"/g,"")),e=Math.max(g.clientWidth||0,y.innerWidth||0),n=Math.max(g.clientHeight||0,y.innerHeight||0),o=["_animation_"+t,"animation_"+t,"_animation","_animation","animation"];Array.from(b.querySelectorAll(".elementor-invisible")).forEach((function(t){var i=t.getBoundingClientRect();if(i.top+y.scrollY<=n&&i.left+y.scrollX<e)try{var a=JSON.parse(t.getAttribute("data-settings"));if(a.trigger_source)return;for(var c,u=a._animation_delay||a.animation_delay||0,f=0;f<o.length;f++)if(a[o[f]]){o[f],c=a[o[f]];break}if(c){var d=w(t),s="none"===c?d:d+" animated "+c,l=setTimeout((function(){E(t,s.replace(/\belementor\-invisible\b/,"")),o.forEach((function(t){return delete a[t]})),t.setAttribute("data-settings",JSON.stringify(a))}),u);r.on("fi",(function(){clearTimeout(l),E(t,w(t).replace(new RegExp("\b"+c+"\b"),""))}))}}catch(t){console.error(t)}}))}))},S=document,A="querySelectorAll",O="data-in-mega_smartmenus",_="DOMContentLoaded",j="readystatechange",P="message",k=console.error;!function(t,e,n,i,c,u,f,d,s){var l,p,m=t.constructor.name+"::",h=e.constructor.name+"::",y=function(e,n){n=n||t;for(var r=0;r<this.length;r++)e.call(n,this[r],r,this)};"NodeList"in t&&!NodeList.prototype.forEach&&(NodeList.prototype.forEach=y),"HTMLCollection"in t&&!HTMLCollection.prototype.forEach&&(HTMLCollection.prototype.forEach=y),_wpspdn["elementor-animations"]&&L(),_wpspdn["elementor-pp"]&&function(){var t=S.createElement("div");t.innerHTML=\'<span class="sub-arrow --wp-meteor"><i class="fa" aria-hidden="true"></i></span>\';var e=t.firstChild;S.addEventListener("DOMContentLoaded",(function(){Array.from(S[A](".pp-advanced-menu ul")).forEach((function(t){if(!t.getAttribute(O)){(t.getAttribute("class")||"").match(/\bmega\-menu\b/)&&t[A]("ul").forEach((function(t){t.setAttribute(O,!0)}));var n=function(t){for(var e=[];t=t.previousElementSibling;)e.push(t);return e}(t),r=n.filter((function(t){return t})).filter((function(t){return"A"===t.tagName})).pop();if(r||(r=n.map((function(t){return Array.from(t[A]("a"))})).filter((function(t){return t})).flat().pop()),r){var o=e.cloneNode(!0);r.appendChild(o),new MutationObserver((function(t){t.forEach((function(t){t.addedNodes.forEach((function(t){if(1===t.nodeType&&"SPAN"===t.tagName)try{r.removeChild(o)}catch(t){}}))}))})).observe(r,{childList:!0})}}}))}))}();var b,g,w=[],E=[],x={},C=!1,T=!1,M=setTimeout;var N=e[n].bind(e),R=e[i].bind(e),H=t[n].bind(t),D=t[i].bind(t);"undefined"!=typeof EventTarget&&(b=EventTarget.prototype.addEventListener,g=EventTarget.prototype.removeEventListener,N=b.bind(e),R=g.bind(e),H=b.bind(t),D=g.bind(t));var z,q=e.createElement.bind(e),B=e.__proto__.__lookupGetter__("readyState").bind(e);Object.defineProperty(e,"readyState",{get:function(){return z||B()},set:function(t){return z=t}});var Q=function(t){return E.filter((function(e,n){var r=e[0],o=(e[1],e[2]);if(!(t.indexOf(r.type)<0)){o||(o=r.target);try{for(var i=o.constructor.name+"::"+r.type,a=0;a<x[i].length;a++){if(x[i][a])if(!W[i+"::"+n+"::"+a])return!0}}catch(t){}}})).length},W={},I=function(t){E.forEach((function(n,r){var o=n[0],i=n[1],a=n[2];if(!(t.indexOf(o.type)<0)){a||(a=o.target);try{var c=a.constructor.name+"::"+o.type;if((x[c]||[]).length)for(var u=0;u<x[c].length;u++){var f=x[c][u];if(f){var d=c+"::"+r+"::"+u;if(!W[d]){W[d]=!0,e.readyState=i;try{f.hasOwnProperty("prototype")&&f.prototype.constructor!==f?f(o):f.bind(a)(o)}catch(t){k(t,f)}}}}}catch(t){k(t)}}}))};N(_,(function(t){E.push([t,e.readyState,e])})),N(j,(function(t){E.push([t,e.readyState,e])})),H(_,(function(n){E.push([n,e.readyState,t])})),H(d,(function(n){E.push([n,e.readyState,t]),G||I([_,j,P,d])}));var J=function(n){E.push([n,e.readyState,t])};H(P,J),r.on("fi",(function(){T=!0,G=!0,e.readyState="loading",M(X)}));H(d,(function t(){C=!0,T&&!G&&(e.readyState="loading",M(X)),D(d,t)})),(new v).init(_wpspdn.rdelay);var F=new a;F.init();var G=!1,X=function n(){var o=w.shift();if(o)if(o[c]("data-src"))o.hasAttribute("data-async")?(U(o),M(n)):U(o,n);else if("javascript/blocked"==o.type)U(o),M(n);else if(o.hasAttribute("data-wpspdn-onload")){var i=o[c]("data-wpspdn-onload");try{new Function(i).call(o)}catch(t){k(t)}M(n)}else M(n);else if(Q([_,j,P]))I([_,j,P]),M(n);else if(T&&C)if(Q([d,P]))I([d,P]),M(n);else{if(t.RocketLazyLoadScripts)try{RocketLazyLoadScripts.run()}catch(t){k(t)}e.readyState="complete",D(P,J),(x[m+"message"]||[]).forEach((function(t){H(P,t)})),F.unmock(),Z=N,$=R,nt=H,rt=D,G=!1,setTimeout((function(){return r.emit("l")}))}else G=!1},Y=function(t){for(var n=e.createElement("SCRIPT"),r=t.attributes,o=r.length-1;o>=0;o--)n.setAttribute(r[o].name,r[o].value);return n.bypass=!0,n.type=t.hasAttribute("data-wpspdn-module")?"module":"text/javascript",(t.text||"").match(/^\s*class RocketLazyLoadScripts/)?n.text=t.text.replace(/^\s*class RocketLazyLoadScripts/,"window.RocketLazyLoadScripts=class").replace("RocketLazyLoadScripts.run();",""):n.text=t.text,n[f]("data-wpspdn-after"),n},K=function(t,e){var n=t.parentNode;n&&n.replaceChild(e,t)},U=function(t,e){if(t[c]("data-src")){var r=Y(t),o=b?b.bind(r):r[n].bind(r);if(e){var i=function(){return M(e)};o(d,i),o(s,i)}r.src=t[c]("data-src"),r[f]("data-src"),K(t,r)}else"javascript/blocked"===t.type?K(t,Y(t)):onLoad&&onLoad()},V=function(t,e){var n=(x[t]||[]).indexOf(e);if(n>=0)return x[t][n]=void 0,!0},Z=function(t,e){if(e&&(t===_||t===j)){var n=h+t;return x[n]=x[n]||[],void x[n].push(e)}for(var r=arguments.length,o=new Array(r>2?r-2:0),i=2;i<r;i++)o[i-2]=arguments[i];return N.apply(void 0,[t,e].concat(o))},$=function(t,e){t===_&&V(h+t,e);return R(t,e)};Object.defineProperties(e,((l={})[n]={get:function(){return Z},set:function(){return Z}},l[i]={get:function(){return $},set:function(){return $}},l)),r.on("pre",(function(){return w.forEach((function(t){var n=t[c]("data-src");if(n){var r=q("link");r.rel="pre"+d,r.as="script",r.href=n,r.crossorigin=!0,e.head.appendChild(r)}}))})),N(_,(function(){e.querySelectorAll("script[data-wpspdn-after]").forEach((function(t){return w.push(t)}));var t=["link"].map((function(t){return t+"[data-wpspdn-onload]"})).join(",");e.querySelectorAll(t).forEach((function(t){return w.push(t)}))}));var tt=function(t){if(e.currentScript)try{var n=e.currentScript.parentElement,r=e.currentScript.nextSibling,i=document.createElement("div");i.innerHTML=t,Array.from(i.childNodes).forEach((function(t){"SCRIPT"===t.nodeName?n.insertBefore(Y(t),r):n.insertBefore(t,r)}))}catch(t){console.error(t)}else k((new Date-o)/1e3,"document.currentScript not set",t)},et=function(t){return tt(t+"\n")};Object.defineProperties(e,{write:{get:function(){return tt},set:function(t){return tt=t}},writeln:{get:function(){return et},set:function(t){return et=t}}});var nt=function(t,e){if(e&&(t===d||t===_||t===P)){var n=t===_?h+t:m+t;return x[n]=x[n]||[],void x[n].push(e)}for(var r=arguments.length,o=new Array(r>2?r-2:0),i=2;i<r;i++)o[i-2]=arguments[i];return H.apply(void 0,[t,e].concat(o))},rt=function(t,e){t===d&&V(t===_?h+t:m+t,e);return D(t,e)};Object.defineProperties(t,((p={})[n]={get:function(){return nt},set:function(){return nt}},p[i]={get:function(){return rt},set:function(){return rt}},p));var ot=function(t){var e;return{get:function(){return e},set:function(n){return e&&V(t,n),x[t]=x[t]||[],x[t].push(n),e=n}}},it=ot(m+d);Object.defineProperty(t,"onload",it),N(_,(function(){Object.defineProperty(e.body,"onload",it)})),Object.defineProperty(e,"onreadystatechange",ot(h+j)),Object.defineProperty(t,"onmessage",ot(m+P));var at=1,ct=function(){--at||r.emit("i")};H(d,(function t(){M((function(){e.querySelectorAll("img").forEach((function(t){if(!t.complete&&(t.currentSrc||t.src)&&"lazy"==!(t.loading||"").toLowerCase()||(r=t.getBoundingClientRect(),o=window.innerHeight||document.documentElement.clientHeight,i=window.innerWidth||document.documentElement.clientWidth,r.top>=-1*o*1&&r.left>=-1*i*1&&r.bottom<=2*o&&r.right<=2*i)){var e=new Image;e[n](d,ct),e[n](s,ct),e.src=t.currentSrc||t.src,at++}var r,o,i})),ct()})),D(d,t)}));var ut=Object.defineProperty;Object.defineProperty=function(n,r,o){return n===t&&["jQuery","onload"].indexOf(r)>=0||(n===e||n===e.body)&&["readyState","write"].indexOf(r)>=0?n:ut(n,r,o)},Object.defineProperties=function(t,e){for(var n in e)Object.defineProperty(t,n,e[n]);return t}}(window,document,"addEventListener","removeEventListener","getAttribute",0,"removeAttribute","load","error")}]);
     157</script></head>',$buffer);
     158       
     159    $cdnurl = str_replace('https://','',get_option('speedien_cdnurl'));
     160   
     161    if(empty($cdnurl))
     162    {
     163        $options = get_option('speedien_options');
     164        $data = array('api_key'=>$options['speedien_field_api_key'], 'site_id' => $options['speedien_field_site_id']);
     165
     166        $response = wp_remote_post(SPEEDIEN_API_URL . '/cdnurl', array('body' => $data, 'timeout' => 10));
     167        if(!empty($response['body']))
     168        {
     169            $cdnurl = str_replace('https://','',$response['body']);
     170        }
     171        else
     172        {
     173            $cdnurl = 'nocdn';
     174        }
     175        update_option('speedien_cdnurl',$cdnurl);
     176    }
     177   
     178    if($cdnurl!== 'nocdn')
     179    {
     180        $site_url = str_replace('https://','',get_site_url());
     181        $buffer = str_replace($site_url.'/wp-content',$cdnurl.'/wp-content',$buffer);
     182        $buffer = str_replace($site_url.'\/wp-content',$cdnurl.'\/wp-content',$buffer);
     183        $buffer = str_replace($site_url.'/wp-includes',$cdnurl.'/wp-includes',$buffer);
     184    }
     185    $buffer = str_replace('</head>','<img width="2100" height="2100" style="pointer-events: none; position: absolute; top: 0; left: 0; width: 90vw; height: 99vh; max-width: 90vw; max-height: 99vh;"  src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHdpZHRoPSI5OTk5OXB4IiBoZWlnaHQ9Ijk5OTk5cHgiIHZpZXdCb3g9IjAgMCA5OTk5OSA5OTk5OSIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj48ZyBzdHJva2U9Im5vbmUiIGZpbGw9Im5vbmUiIGZpbGwtb3BhY2l0eT0iMCI+PHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9Ijk5OTk5IiBoZWlnaHQ9Ijk5OTk5Ij48L3JlY3Q+IDwvZz4gPC9zdmc+"></head>',$buffer);
     186    return $buffer;
     187}
     188
     189add_action( 'template_redirect', 'speedien_process_page');
     190
     191function speedien_exclusion_handler($replace, $string ) {
    48192    $options = get_option('speedien_options');
    49     $api_key = sanitize_key($options['speedien_field_api_key']);
    50     $site_id = sanitize_key($options['speedien_field_site_id']);
    51     if(!empty($_GET))
    52     {
    53     $query = '?';
    54     $get = array_map( 'sanitize_text_field', $_GET );
    55     foreach($get as $k => $v)
    56     {
    57         if(strpos($k, 'utm') !== false)
    58         {
    59             unset($_GET[$k]); continue;
    60         }
    61         if(strpos($k, 'clid') !== false)
    62         {
    63             unset($_GET[$k]); continue;
    64         }
    65         if(strpos($k, 'ref') !== false)
    66         {
    67             unset($_GET[$k]); continue;
    68         }
    69         $query .= $k.'='.$v.'&';
    70     }
    71     }
    72 
    73     $host = $_SERVER['HTTP_HOST'];
    74     $path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
    75     if(!empty($query))
    76     {
    77         $path = $path.urlencode($query);
    78     }
    79     $response = wp_remote_post(SPEEDIEN_API_URL . '/process', array('body' => array('api_key' => $api_key, 'site_id' => $site_id, 'host' => $host, 'path' => $path, 'buffer' => $buffer,),'timeout' => 10,));
    80     return $buffer;
    81 }
    82 
    83 speedien_process_page();
    84 
    85 function speedien_verify_hmac()
    86 {
    87     $options = get_option('speedien_options');
    88     $api_key = $options['speedien_field_api_key'];
    89     $site_id = $options['speedien_field_site_id'];
    90 
    91     if(empty($_POST))
    92     {
     193    $jse_type = 1;
     194    if(!empty($options['speedien_field_jse_type']))
     195    {
     196        $jse_type = $options['speedien_field_jse_type'];
     197    }
     198    if($jse_type == 1)
     199    {
     200        if(!empty($options['speedien_field_jslist']))
     201        {
     202            $js_exclusions = explode(PHP_EOL, $options['speedien_field_jslist']);
     203            foreach($js_exclusions as $exclusion)
     204            {
     205                if(strpos($string, trim($exclusion)) !== false)
     206                {
     207                    return $string;
     208                }
     209                if(strpos('exclude_all', trim($exclusion)) !== false)
     210                {
     211                    return true;
     212                }
     213            }
     214        }
    93215        return false;
    94216    }
    95217    else
    96218    {
    97         $response = sanitize_html_class($_POST['response']);
    98 
    99         $data = json_decode(base64_decode($response), true);
    100         $signature = $data['signature'];
    101         $contents = $data['contents'];
    102     }
    103     $parameters = sanitize_text_field($api_key. $site_id . $contents);
    104     $hmac = hash_hmac('sha256', $parameters, $api_key);
    105     return ($hmac == $signature);
    106 }
    107 
    108 function speedien_store_cache()
    109 {
    110     if($_SERVER["REQUEST_URI"] == '/wp-admin/speedien' && $_SERVER['REQUEST_METHOD'] == 'POST')
    111     {
    112         if(speedien_verify_hmac())
    113         {
    114             $response = sanitize_html_class($_POST['response']);
    115 
    116             $data = json_decode(base64_decode($response), true);
    117             $url = urldecode($data['url']);
    118             $cleaned_url = str_replace(array('?','&','='),'-',$url);
    119             $url = rtrim($cleaned_url, '/') . '/';
    120             $action = $data['action'];
    121             if($action == 'cache')
    122             {
    123                 $cache_file_path = WP_CONTENT_DIR . "/cache/speedien/$url" . 'index.html';
    124                 $contents = base64_decode($data['contents']);
    125                 mkdir(WP_CONTENT_DIR . "/cache/speedien/$url",0755,true);
    126                 if(!file_put_contents($cache_file_path,$contents))
     219        if(!empty($options['speedien_field_jslist']))
     220        {
     221            $js_exclusions = explode(PHP_EOL, $options['speedien_field_jslist']);
     222            foreach($js_exclusions as $exclusion)
     223            {
     224                if(strpos($string, trim($exclusion)) !== false)
    127225                {
    128                     die('Encountered an error while storing cached response.');
    129                 }
    130                 $css = base64_decode($data['css']);
    131                 if(!file_put_contents(WP_CONTENT_DIR . "/cache/speedien/$url" . "style.css",$css))
    132                 {
    133                     die('Encountered an error while storing css.');
    134                 }
    135             }
    136             if($action == 'dropin')
    137             {
    138                 $cache_file_path = WP_CONTENT_DIR . '/advanced-cache.php';
    139                 $contents = base64_decode($data['contents']);
    140                 if(!file_put_contents($cache_file_path,$contents))
    141                 {
    142                     die('Encountered an error while updating cache drop-in.');
    143                 }
    144             }
    145             if($action == 'purge')
    146             {
    147                 speedien_purge();
    148             }
    149         }
    150         else
    151         {
    152             header('HTTP/1.0 403 Forbidden');
    153         }
    154         exit();
    155     }
    156 }
    157 
    158 add_action('parse_request', 'speedien_store_cache');
     226                    return false;
     227                }
     228            }
     229            return true;
     230        }
     231    }
     232   
     233}
     234add_filter( 'wpspdn_exclude', 'speedien_exclusion_handler', 10, 3 );
  • speedien/tags/1.1.0/speedien_ui.php

    r2503641 r2664756  
    11<?php
    22
    3 /**
    4  * @internal never define functions inside callbacks.
    5  * these functions could be run multiple times; this would result in a fatal error.
    6  */
    7 
    8 /**
    9  * custom option and settings
    10  */
    113function speedien_settings_init()
    124{
     
    157
    168    // Register a new section in the "speedien" page.
     9    $options = get_option('speedien_options');
     10   
    1711    add_settings_section(
    1812        'speedien_section_developers',
    19         __('Connect to your Speedien Account ', 'speedien'),
     13        __('Pagespeed Optimization Settings ', 'speedien'),
    2014        'speedien_section_developers_callback',
    2115        'speedien'
     
    3832    // Register a new field in the "speedien_section_developers" section, inside the "speedien" page.
    3933    add_settings_field(
    40         'speedien_field_api_key', // As of WP 4.6 this value is used only internally.
    41         // Use $args' label_for to populate the id inside the callback.
     34        'speedien_field_api_key',
    4235        __('Speedien API Key', 'speedien'),
    4336        'speedien_field_api_key_cb',
     
    5144    );
    5245
    53     speedien_cache_init();
     46    add_settings_field(
     47        'speedien_field_jse_type',
     48        __('Javascript Exclusion Type', 'speedien'),
     49        'speedien_field_jse_type_cb',
     50        'speedien',
     51        'speedien_section_developers',
     52        array(
     53            'label_for'            => 'speedien_field_jse_type',
     54            'class'                => 'speedien_row',
     55            'speedien_custom_data' => 'custom',
     56        )
     57    );
     58
     59    add_settings_field(
     60        'speedien_field_jslist',
     61        __('Javascript Exclusion List', 'speedien'),
     62        'speedien_field_jslist_cb',
     63        'speedien',
     64        'speedien_section_developers',
     65        array(
     66            'label_for'            => 'speedien_field_jslist',
     67            'class'                => 'speedien_row',
     68            'speedien_custom_data' => 'custom',
     69        )
     70    );
     71
     72    add_settings_field(
     73        'speedien_field_pagelist',
     74        __('Exclude pages from optimization', 'speedien'),
     75        'speedien_field_pagelist_cb',
     76        'speedien',
     77        'speedien_section_developers',
     78        array(
     79            'label_for'            => 'speedien_field_pagelist',
     80            'class'                => 'speedien_row',
     81            'speedien_custom_data' => 'custom',
     82        )
     83    );
    5484
    5585}
     
    6292function speedien_cache_init()
    6393{
    64     $wp_config_file = ABSPATH . 'wp-config.php';
    65     if (!file_exists($wp_config_file)) {
    66         $wp_config_file = dirname(ABSPATH) . '/wp-config.php';
    67     }
    68     if (!file_exists($wp_config_file) || !is_writable($wp_config_file)) {
    69         return;
    70     }
    71 
    72     $content = "\ndefine('WP_CACHE', true); // Speedien cache handler";
    73     $wp_config = file_get_contents($wp_config_file);
    74     $wp_cache = '/define\([\'\"]WP_CACHE[\'\"].*/';
    75     $wp_config = preg_replace($wp_cache, '', $wp_config);
    76     $wp_config = str_replace('<?php', '<?php' . $content, $wp_config);
    77     file_put_contents($wp_config_file, $wp_config);
    78 
    79     $plugindir = plugin_dir_path( __FILE__ );
    80     $advanced_cache = file_get_contents($plugindir . '/advanced-cache.php');
    81     file_put_contents(WP_CONTENT_DIR . '/advanced-cache.php', $advanced_cache);
     94    file_put_contents(WP_CONTENT_DIR . '/advanced-cache.php', '');
    8295}
    8396
     
    95108function speedien_section_developers_callback($args)
    96109{
    97 ?>
    98 
    99 <p id="<?php echo esc_attr($args['id']); ?>">Please visit <a href="https://my.speedien.com/sites">https://my.speedien.com/sites</a> to find your API key and Site ID.</p>
    100 <?php
     110
     111    $options = get_option('speedien_options');
     112   
     113    if(empty($options['speedien_field_api_key']) || empty($options['speedien_field_site_id']))
     114    {
     115?>
     116
     117<p id="<?php echo esc_attr($args['id']); ?>">Please visit <a href="https://my.speedien.com/signup" target="_blank">https://my.speedien.com/signup</a> to generate a new API key and Site ID.</p>
     118<?php
     119    }
    101120}
    102121
    103     /**
    104      * Pill field callback function.
    105      *
    106      * WordPress has magic interaction with the following keys: label_for, class.
    107      * - the "label_for" key value is used for the "for" attribute of the <label>.
    108      * - the "class" key value is used for the "class" attribute of the <tr> containing the field.
    109      * Note: you can add custom key value pairs to be used inside your callbacks.
    110      *
    111      * @param array $args
    112      */
    113122    function speedien_field_api_key_cb($args)
    114123    {
     
    123132    ?>
    124133
    125 <input type="text" name="speedien_options[<?php echo esc_attr($args['label_for']); ?>]"
     134<input type="password" name="speedien_options[<?php echo esc_attr($args['label_for']); ?>]"
    126135    id="<?php echo esc_attr($args['label_for']); ?>" value="<?php echo $api_key; ?>" />
    127136
     
    141150?>
    142151
    143 <input type="text" name="speedien_options[<?php echo esc_attr($args['label_for']); ?>]"
     152<input type="password" name="speedien_options[<?php echo esc_attr($args['label_for']); ?>]"
    144153    id="<?php echo esc_attr($args['label_for']); ?>" value="<?php echo $api_key; ?>" />
    145154
     
    147156    }
    148157
     158    function speedien_field_pagelist_cb($args)
     159    {
     160        // Get the value of the setting we've registered with register_setting()
     161        $options = get_option('speedien_options');
     162        if (isset($options[$args['label_for']])) {
     163            $page_exclusions = esc_attr($options[$args['label_for']]);
     164        } else {
     165            $page_exclusions = '';
     166        }
     167
     168?>
     169
     170<textarea name="speedien_options[<?php echo esc_attr($args['label_for']); ?>]"
     171    id="<?php echo esc_attr($args['label_for']); ?>" rows="4" cols="40"><?php echo $page_exclusions; ?></textarea>
     172    <br><span>Enter the slugs of the pages that you wish to exclude from optimization. (Example: /contact)</span>
     173<?php
     174    }
     175
     176    function speedien_field_jse_type_cb($args)
     177    {
     178        // Get the value of the setting we've registered with register_setting()
     179        $options = get_option('speedien_options');
     180        if (isset($options[$args['label_for']])) {
     181            $jse_type = esc_attr($options[$args['label_for']]);
     182        } else {
     183            $jse_type = '1';
     184        }
     185
     186?>
     187<input type="radio" name="speedien_options[<?php echo esc_attr($args['label_for']); ?>]" value="1" <?php checked(1, $jse_type, true); ?>>Exclude all Javascript except for the following list.<br /><br />
     188<input type="radio" name="speedien_options[<?php echo esc_attr($args['label_for']); ?>]" value="2" <?php checked(2, $jse_type, true); ?>>Exclude only Javascript matching the following list.
     189
     190
     191<?php
     192    }
     193
     194    function speedien_field_jslist_cb($args)
     195    {
     196        // Get the value of the setting we've registered with register_setting()
     197        $options = get_option('speedien_options');
     198        if (isset($options[$args['label_for']])) {
     199            $js_exclusions = esc_attr($options[$args['label_for']]);
     200        } else {
     201            $js_exclusions = '';
     202        }
     203
     204?>
     205
     206<textarea name="speedien_options[<?php echo esc_attr($args['label_for']); ?>]"
     207    id="<?php echo esc_attr($args['label_for']); ?>" rows="4" cols="40"><?php echo $js_exclusions; ?></textarea>
     208    <br><span>Enter the keyword from javascript code or url. (Example: gtm.js)</span>
     209<?php
     210    }
     211
     212   
    149213    /**
    150214     * Add the top level menu page.
     
    153217    {
    154218        add_menu_page(
    155             'Speedien Options',
    156             'Speedien ',
     219            'Pagespeed Optimization Settings',
     220            'Pagespeed ',
    157221            'manage_options',
    158222            'speedien',
     
    190254
    191255        settings_errors('speedien_messages');
     256
     257        $options = get_option('speedien_options');
     258
    192259?>
    193260<div class="wrap">
    194261
    195262    <form action="options.php" method="post" class="speedien-form-bg">
    196         <h1><?php echo esc_html(get_admin_page_title()); ?></h1>
    197         <hr />
    198263        <?php
    199264            // output security fields for the registered setting "speedien"
     
    218283
    219284</div>
    220 <?php
    221     }
     285
     286<?php
     287    }
     288
     289    function speedien_section_preload_callback( $arg ) { ?>
     290        <input type="hidden" name="action" value="speedien_preload_content">
     291        <?php
     292    }
     293
     294    function speedien_preload_content_handler() {
     295        update_option('speedien_preload_status','In Progress');
     296       
     297        $preloadurls = array();
     298        $pages = get_pages(array('number' => 100));
     299        foreach($pages as $page)
     300        {
     301            $preloadurls[] = get_permalink($page->ID);
     302        }
     303        $posts = get_posts(array('number' => 50));
     304        foreach($posts as $post)
     305        {
     306            $preloadurls[] = get_permalink($post->ID);
     307        }
     308
     309        $options = get_option('speedien_options');
     310        $data = array('api_key'=>$options['speedien_field_api_key'], 'site_id' => $options['speedien_field_site_id'], 'urls' => $preloadurls);
     311
     312        $response = wp_remote_post(SPEEDIEN_API_URL . '/preload', array('body' => $data, 'timeout' => 10));
     313        wp_redirect(admin_url('admin.php?page=speedien'));
     314    }
     315    add_action( 'admin_post_speedien_preload_content', 'speedien_preload_content_handler' );
Note: See TracChangeset for help on using the changeset viewer.