improvements to Varnish configs like websocket support, remove the Google Analytics added parameters, strip hash, remove unnecessary cookies
improvements to Varnish configs like websocket support, remove the Google Analytics added parameters, strip hash, remove unnecessary cookies

file:a/readme.txt -> file:b/readme.txt
--- a/readme.txt
+++ b/readme.txt
@@ -1,10 +1,10 @@
 === Varnish Caching ===
-Donate link: www.paypal.com/use/email/razvan_stanga@yahoo.com
+Donate link: http://git.razvi.ro/
 Contributors: razvanstanga
 Tags: varnish, purge, cache, caching, optimization, performance, traffic
 Requires at least: 4.0
-Tested up to: 4.5
-Stable tag: 1.4.3
+Tested up to: 4.7
+Stable tag: 1.5.4
 License: GPLv2 or later
 
 Wordpress Varnish Cache 3.x/4.x integration
@@ -53,10 +53,6 @@
 
 * https://wordpress.org/plugins/varnish-http-purge/
 * https://github.com/dreamhost/varnish-vcl-collection/
-
-Implemented on :
-
-* www.bvoltaire.fr
 
 == Installation ==
 
@@ -110,7 +106,35 @@
 This is a small step towards securing your site for denial of service attacks. Denial of service attacks can happen if the attacker bypasses Varnish Cache and hits the backend directly.
 With the current configuration and the way Wordpress works, this can still happen with POST/AJAX requests.
 
+= Available filters =
+
+* `vcaching_varnish_ips` - change the IPs set in Settings
+* `vcaching_varnish_hosts` - change the Hosts set in Settings
+* `vcaching_events` - add events to trigger the purge
+* `vcaching_schema` - change the schema (default is http://)
+* `vcaching_purge_urls` - add additional URLs to purge
+
 == Changelog ==
+
+= 1.5.4 =
+* improvements to Varnish configs like websocket support, remove the Google Analytics added parameters, strip hash, remove unnecessary cookies
+
+= 1.5.3 =
+* hardcoded on/off VCL Generator, filters added to readme
+
+= 1.5.2 =
+* added AMP URL purge
+
+= 1.5.1 =
+* fixed PHP notices
+* tested with 4.6
+
+= 1.5 =
+* `Purge from Varnish` post/page action link
+* removed 10 chars logged in cookie restriction
+* code cleanup/some wp coding standards
+* vcaching_varnish_ips filter
+* vcaching_varnish_hosts filter
 
 = 1.4.3 =
 * Truncate option added for too many 'trying to purge' messages. Added check for ZipArchive class to download VCLs.

--- a/varnish-conf/v3/default.vcl
+++ b/varnish-conf/v3/default.vcl
@@ -21,6 +21,11 @@
         return(pipe);
     }
 
+    # Implementing websocket support (https://www.varnish-cache.org/docs/4.0/users-guide/vcl-example-websockets.html)
+    if (req.http.Upgrade ~ "(?i)websocket") {
+        return (pipe);
+    }
+
     # redirect yourdomain.com to www.yourdomain.com
     #if (req.http.host ~ "^yourdomain\.com$") {
     #    error 750 "http://www.yourdomain.com" + req.url;
@@ -40,7 +45,7 @@
     }
 
     # don't cache logged-in users. you can set users `logged in cookie` name in settings
-    if (req.http.Cookie ~ "c005492c65") {
+    if (req.http.Cookie ~ "flxn34napje9kwbwr4bjwz5miiv9dhgj87dct4ep0x3arr7ldif73ovpxcgm88vs") {
         set req.http.X-VC-Cacheable = "NO:Found logged in cookie";
         return(pass);
     }
@@ -69,10 +74,50 @@
     #}
 
     # Remove has_js, Google Analytics __*, and wooTracker cookies.
-    set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(__[a-z]+|has_js|wooTracker)=[^;]*", "");
+    set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(has_js|wooTracker)=[^;]*", "");
+    set req.http.Cookie = regsuball(req.http.Cookie, "__utm.=[^;]+(; )?", "");
+    set req.http.Cookie = regsuball(req.http.Cookie, "_ga=[^;]+(; )?", "");
+    set req.http.Cookie = regsuball(req.http.Cookie, "_gat=[^;]+(; )?", "");
+    set req.http.Cookie = regsuball(req.http.Cookie, "utmctr=[^;]+(; )?", "");
+    set req.http.Cookie = regsuball(req.http.Cookie, "utmcmd.=[^;]+(; )?", "");
+    set req.http.Cookie = regsuball(req.http.Cookie, "utmccn.=[^;]+(; )?", "");
     set req.http.Cookie = regsub(req.http.Cookie, "^;\s*", "");
+    # Remove DoubleClick offensive cookies
+    set req.http.Cookie = regsuball(req.http.Cookie, "__gads=[^;]+(; )?", "");
+
+    # Remove the Quant Capital cookies (added by some plugin, all __qca)
+    set req.http.Cookie = regsuball(req.http.Cookie, "__qc.=[^;]+(; )?", "");
+
+    # Remove the AddThis cookies
+    set req.http.Cookie = regsuball(req.http.Cookie, "__atuv.=[^;]+(; )?", "");
+
+    # Remove a ";" prefix in the cookie if present
+    set req.http.Cookie = regsuball(req.http.Cookie, "^;\s*", "");
+
+    # Are there cookies left with only spaces or that are empty?
     if (req.http.Cookie ~ "^\s*$") {
         unset req.http.Cookie;
+    }
+
+    # Protecting against the HTTPOXY CGI vulnerability.
+    unset req.http.proxy;
+
+    # Remove the Google Analytics added parameters.
+    if (req.url ~ "(\?|&)(utm_source|utm_medium|utm_campaign|utm_content|gclid|cx|ie|cof|siteurl)=") {
+        set req.url = regsuball(req.url, "&(utm_source|utm_medium|utm_campaign|utm_content|gclid|cx|ie|cof|siteurl)=([A-z0-9_\-\.%25]+)", "");
+        set req.url = regsuball(req.url, "\?(utm_source|utm_medium|utm_campaign|utm_content|gclid|cx|ie|cof|siteurl)=([A-z0-9_\-\.%25]+)", "?");
+        set req.url = regsub(req.url, "\?&", "?");
+        set req.url = regsub(req.url, "\?$", "");
+    }
+
+    # Strip hash, server doesn't need it.
+    if (req.url ~ "\#") {
+        set req.url = regsub(req.url, "\#.*$", "");
+    }
+
+    # Strip a trailing ? if it exists
+    if (req.url ~ "\?$") {
+        set req.url = regsub(req.url, "\?$", "");
     }
 
     return(lookup);
@@ -157,3 +202,9 @@
     }
 }
 
+sub vcl_pipe {
+     if (req.http.upgrade) {
+         set bereq.http.upgrade = req.http.upgrade;
+     }
+}
+

--- a/varnish-conf/v4/default.vcl
+++ b/varnish-conf/v4/default.vcl
@@ -23,6 +23,11 @@
         return(pipe);
     }
 
+    # Implementing websocket support (https://www.varnish-cache.org/docs/4.0/users-guide/vcl-example-websockets.html)
+    if (req.http.Upgrade ~ "(?i)websocket") {
+        return (pipe);
+    }
+
     # redirect yourdomain.com to www.yourdomain.com
     #if (req.http.host ~ "^yourdomain\.com$") {
     #    set req.http.X-VC-Redirect = "http://www.yourdomain.com" + req.url;
@@ -43,7 +48,7 @@
     }
 
     # don't cache logged-in users. you can set users `logged in cookie` name in settings
-    if (req.http.Cookie ~ "c005492c65") {
+    if (req.http.Cookie ~ "flxn34napje9kwbwr4bjwz5miiv9dhgj87dct4ep0x3arr7ldif73ovpxcgm88vs") {
         set req.http.X-VC-Cacheable = "NO:Found logged in cookie";
         return(pass);
     }
@@ -71,11 +76,54 @@
     #}
 
     # Remove has_js, Google Analytics __*, and wooTracker cookies.
-    set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(__[a-z]+|has_js|wooTracker)=[^;]*", "");
+    set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(has_js|wooTracker)=[^;]*", "");
+    set req.http.Cookie = regsuball(req.http.Cookie, "__utm.=[^;]+(; )?", "");
+    set req.http.Cookie = regsuball(req.http.Cookie, "_ga=[^;]+(; )?", "");
+    set req.http.Cookie = regsuball(req.http.Cookie, "_gat=[^;]+(; )?", "");
+    set req.http.Cookie = regsuball(req.http.Cookie, "utmctr=[^;]+(; )?", "");
+    set req.http.Cookie = regsuball(req.http.Cookie, "utmcmd.=[^;]+(; )?", "");
+    set req.http.Cookie = regsuball(req.http.Cookie, "utmccn.=[^;]+(; )?", "");
     set req.http.Cookie = regsub(req.http.Cookie, "^;\s*", "");
+    # Remove DoubleClick offensive cookies
+    set req.http.Cookie = regsuball(req.http.Cookie, "__gads=[^;]+(; )?", "");
+
+    # Remove the Quant Capital cookies (added by some plugin, all __qca)
+    set req.http.Cookie = regsuball(req.http.Cookie, "__qc.=[^;]+(; )?", "");
+
+    # Remove the AddThis cookies
+    set req.http.Cookie = regsuball(req.http.Cookie, "__atuv.=[^;]+(; )?", "");
+
+    # Remove a ";" prefix in the cookie if present
+    set req.http.Cookie = regsuball(req.http.Cookie, "^;\s*", "");
+
+    # Are there cookies left with only spaces or that are empty?
     if (req.http.Cookie ~ "^\s*$") {
         unset req.http.Cookie;
     }
+
+    # Protecting against the HTTPOXY CGI vulnerability.
+    unset req.http.proxy;
+
+    # Remove the Google Analytics added parameters.
+    if (req.url ~ "(\?|&)(utm_source|utm_medium|utm_campaign|utm_content|gclid|cx|ie|cof|siteurl)=") {
+        set req.url = regsuball(req.url, "&(utm_source|utm_medium|utm_campaign|utm_content|gclid|cx|ie|cof|siteurl)=([A-z0-9_\-\.%25]+)", "");
+        set req.url = regsuball(req.url, "\?(utm_source|utm_medium|utm_campaign|utm_content|gclid|cx|ie|cof|siteurl)=([A-z0-9_\-\.%25]+)", "?");
+        set req.url = regsub(req.url, "\?&", "?");
+        set req.url = regsub(req.url, "\?$", "");
+    }
+
+    # Strip hash, server doesn't need it.
+    if (req.url ~ "\#") {
+        set req.url = regsub(req.url, "\#.*$", "");
+    }
+
+    # Strip a trailing ? if it exists
+    if (req.url ~ "\?$") {
+        set req.url = regsub(req.url, "\?$", "");
+    }
+
+    # Normalize the query arguments
+    set req.url = std.querysort(req.url);
 
     return(hash);
 }
@@ -162,3 +210,9 @@
     }
 }
 
+sub vcl_pipe {
+     if (req.http.upgrade) {
+         set bereq.http.upgrade = req.http.upgrade;
+     }
+}
+

--- a/vcaching.php
+++ b/vcaching.php
@@ -3,14 +3,14 @@
 Plugin Name: Varnish Caching
 Plugin URI: http://wordpress.org/extend/plugins/vcaching/
 Description: WordPress Varnish Cache integration.
-Version: 1.4.3
+Version: 1.5.4
 Author: Razvan Stanga
 Author URI: http://git.razvi.ro/
 License: http://www.apache.org/licenses/LICENSE-2.0
 Text Domain: vcaching
 Network: true
 
-Copyright 2015: Razvan Stanga (email: varnish-caching@razvi.ro)
+Copyright 2016: Razvan Stanga (email: varnish-caching@razvi.ro)
 */
 
 class VCaching {
@@ -30,7 +30,9 @@
     protected $customFields = array();
     protected $noticeMessage = '';
     protected $truncateNotice = false;
+    protected $truncateCount = 0;
     protected $debug = 0;
+    protected $vclGeneratorTab = true;
 
     public function __construct()
     {
@@ -40,6 +42,11 @@
         $this->blogId = $blog_id;
         add_action('init', array(&$this, 'init'));
         add_action('activity_box_end', array($this, 'varnish_glance'), 100);
+    }
+
+    public function init()
+    {
+        load_plugin_textdomain($this->plugin, false, plugin_basename( dirname( __FILE__ ) ) . '/languages' );
 
         $this->customFields = array(
             array(
@@ -52,14 +59,9 @@
             )
         );
 
-        $this->setupIpsToHosts();
+        $this->setup_ips_to_hosts();
         $this->purgeKey = ($purgeKey = trim(get_option($this->prefix . 'purge_key'))) ? $purgeKey : null;
         $this->admin_menu();
-    }
-
-    public function init()
-    {
-        load_plugin_textdomain($this->plugin, false, plugin_basename( dirname( __FILE__ ) ) . '/languages' );
 
         add_action('wp', array($this, 'buffer_start'), 1000000);
         add_action('shutdown', array($this, 'buffer_end'), 1000000);
@@ -75,35 +77,59 @@
         add_action('wp_logout', array($this, 'wp_logout'), 1000000);
 
         // register events to purge post
-        foreach ($this->getRegisterEvents() as $event) {
+        foreach ($this->get_register_events() as $event) {
             add_action($event, array($this, 'purge_post'), 10, 2);
         }
 
-        // purge all cache
-        if (isset($_GET[$this->getParam]) && check_admin_referer($this->plugin)) {
-            if (get_option('permalink_structure') == '' && current_user_can('manage_options')) {
-                add_action('admin_notices' , array($this, 'pretty_permalinks_message'));
-            }
-            if ($this->varnishIp == null) {
-                add_action('admin_notices' , array($this, 'purge_message_no_ips'));
-            } else {
-                $this->purgeCache();
-            }
-        }
-
+        // purge all cache from admin bar
         if ($this->check_if_purgeable()) {
             add_action('admin_bar_menu', array($this, 'purge_varnish_cache_all_adminbar'), 100);
-        }
+            if (isset($_GET[$this->getParam]) && check_admin_referer($this->plugin)) {
+                if (get_option('permalink_structure') == '' && current_user_can('manage_options')) {
+                    add_action('admin_notices' , array($this, 'pretty_permalinks_message'));
+                }
+                if ($this->varnishIp == null) {
+                    add_action('admin_notices' , array($this, 'purge_message_no_ips'));
+                } else {
+                    $this->purge_cache();
+                }
+            }
+        }
+
+        // purge post/page cache from post/page actions
+        if ($this->check_if_purgeable()) {
+            if(!session_id()) {
+                session_start();
+            }
+            add_filter('post_row_actions', array(
+                &$this,
+                'post_row_actions'
+            ), 0, 2);
+            add_filter('page_row_actions', array(
+                &$this,
+                'page_row_actions'
+            ), 0, 2);
+            if (isset($_GET['action']) && isset($_GET['post_id']) && ($_GET['action'] == 'purge_post' || $_GET['action'] == 'purge_page') && check_admin_referer($this->plugin)) {
+                $this->purge_post($_GET['post_id']);
+                $_SESSION['vcaching_note'] = $this->noticeMessage;
+                $referer = str_replace('purge_varnish_cache=1', '', wp_get_referer());
+                wp_redirect($referer . (strpos($referer, '?') ? '&' : '?') . 'vcaching_note=' . $_GET['action']);
+            }
+            if (isset($_GET['vcaching_note']) && ($_GET['vcaching_note'] == 'purge_post' || $_GET['vcaching_note'] == 'purge_page')) {
+                add_action('admin_notices' , array($this, 'purge_post_page'));
+            }
+        }
+
         if ($this->override = get_option($this->prefix . 'override')) {
-            add_action('admin_menu', array($this, 'createCustomFields'));
-            add_action('save_post', array($this, 'saveCustomFields' ), 1, 2);
+            add_action('admin_menu', array($this, 'create_custom_fields'));
+            add_action('save_post', array($this, 'save_custom_fields' ), 1, 2);
             add_action('wp_enqueue_scripts', array($this, 'override_ttl'), 1000);
         }
         add_action('wp_enqueue_scripts', array($this, 'override_homepage_ttl'), 1000);
 
         // console purge
-        if (isset($_POST['varnish_caching_purge_url'])) {
-            $this->purgeUrl(home_url() . $_POST['varnish_caching_purge_url']);
+        if ($this->check_if_purgeable() && isset($_POST['varnish_caching_purge_url'])) {
+            $this->purge_url(home_url() . $_POST['varnish_caching_purge_url']);
             add_action('admin_notices' , array($this, 'purge_message'));
         }
     }
@@ -142,14 +168,16 @@
         ob_end_flush();
     }
 
-    protected function setupIpsToHosts()
+    protected function setup_ips_to_hosts()
     {
         $this->varnishIp = get_option($this->prefix . 'ips');
         $this->varnishHost = get_option($this->prefix . 'hosts');
         $this->dynamicHost = get_option($this->prefix . 'dynamic_host');
         $this->statsJsons = get_option($this->prefix . 'stats_json_file');
         $varnishIp = explode(',', $this->varnishIp);
+        $varnishIp = apply_filters('vcaching_varnish_ips', $varnishIp);
         $varnishHost = explode(',', $this->varnishHost);
+        $varnishHost = apply_filters('vcaching_varnish_hosts', $varnishHost);
         $statsJsons = explode(',', $this->statsJsons);
         foreach ($varnishIp as $key => $ip) {
             $this->ipsToHosts[] = array(
@@ -160,16 +188,16 @@
         }
     }
 
-    public function createCustomFields()
+    public function create_custom_fields()
     {
         if (function_exists('add_meta_box')) {
             foreach ($this->postTypes as $postType) {
-                add_meta_box($this->plugin, 'Varnish', array($this, 'displayCustomFields'), $postType, 'side', 'high');
-            }
-        }
-    }
-
-    public function saveCustomFields($post_id, $post)
+                add_meta_box($this->plugin, __('Varnish Caching', $this->plugin), array($this, 'display_custom_fields'), $postType, 'side', 'high');
+            }
+        }
+    }
+
+    public function save_custom_fields($post_id, $post)
     {
         if (!isset($_POST['vc-custom-fields_wpnonce']) || !wp_verify_nonce($_POST['vc-custom-fields_wpnonce'], 'vc-custom-fields'))
             return;
@@ -188,58 +216,56 @@
         }
     }
 
-    public function displayCustomFields()
+    public function display_custom_fields()
     {
         global $post;
-        ?>
-            <?php
-            wp_nonce_field('vc-custom-fields', 'vc-custom-fields_wpnonce', false, true);
-            foreach ($this->customFields as $customField) {
-                // Check scope
-                $scope = $customField['scope'];
+        wp_nonce_field('vc-custom-fields', 'vc-custom-fields_wpnonce', false, true);
+        foreach ($this->customFields as $customField) {
+            // Check scope
+            $scope = $customField['scope'];
+            $output = false;
+            foreach ($scope as $scopeItem) {
+                switch ($scopeItem) {
+                    default: {
+                        if ($post->post_type == $scopeItem)
+                            $output = true;
+                        break;
+                    }
+                }
+                if ($output) break;
+            }
+            // Check capability
+            if (!current_user_can($customField['capability'], $post->ID))
                 $output = false;
-                foreach ($scope as $scopeItem) {
-                    switch ($scopeItem) {
-                        default: {
-                            if ($post->post_type == $scopeItem)
-                                $output = true;
-                            break;
-                        }
+            // Output if allowed
+            if ($output) {
+                switch ($customField['type']) {
+                    case "checkbox": {
+                        // Checkbox
+                        echo '<p><strong>' . $customField['title'] . '</strong></p>';
+                        echo '<label class="screen-reader-text" for="' . $this->prefix . $customField['name'] . '">' . $customField['title'] . '</label>';
+                        echo '<p><input type="checkbox" name="' . $this->prefix . $customField['name'] . '" id="' . $this->prefix . $customField['name'] . '" value="yes"';
+                        if (get_post_meta($post->ID, $this->prefix . $customField['name'], true ) == "yes")
+                            echo ' checked="checked"';
+                        echo '" style="width: auto;" /></p>';
+                        break;
                     }
-                    if ($output) break;
-                }
-                // Check capability
-                if (!current_user_can($customField['capability'], $post->ID))
-                    $output = false;
-                // Output if allowed
-                if ($output) { ?>
-                        <?php
-                        switch ($customField['type']) {
-                            case "checkbox": {
-                                // Checkbox
-                                echo '<p><strong>' . $customField['title'] . '</strong></p>';
-                                echo '<label class="screen-reader-text" for="' . $this->prefix . $customField['name'] . '">' . $customField['title'] . '</label>';
-                                echo '<p><input type="checkbox" name="' . $this->prefix . $customField['name'] . '" id="' . $this->prefix . $customField['name'] . '" value="yes"';
-                                if (get_post_meta($post->ID, $this->prefix . $customField['name'], true ) == "yes")
-                                    echo ' checked="checked"';
-                                echo '" style="width: auto;" /></p>';
-                                break;
-                            }
-                            default: {
-                                // Plain text field
-                                echo '<p><b>' . $customField['title'] . '</b></p>';
-                                $value = get_post_meta($post->ID, $this->prefix . $customField[ 'name' ], true);
-                                $default_ttl = get_option($this->prefix . 'ttl');
-                                echo '<p><input type="text" name="' . $this->prefix . $customField['name'] . '" id="' . $this->prefix . $customField['name'] . '" value="' . $value . '" /></p>';
-                                break;
-                            }
-                        }
-                        ?>
-                        <?php if ($customField['description']) echo '<p>' . sprintf($customField['description'], $default_ttl) . '</p>'; ?>
-                <?php
-                }
-            } ?>
-        <?php
+                    default: {
+                        // Plain text field
+                        echo '<p><strong>' . $customField['title'] . '</strong></p>';
+                        $value = get_post_meta($post->ID, $this->prefix . $customField[ 'name' ], true);
+                        echo '<p><input type="text" name="' . $this->prefix . $customField['name'] . '" id="' . $this->prefix . $customField['name'] . '" value="' . $value . '" /></p>';
+                        break;
+                    }
+                }
+            } else {
+                echo '<p><strong>' . $customField['title'] . '</strong></p>';
+                $value = get_post_meta($post->ID, $this->prefix . $customField[ 'name' ], true);
+                echo '<p><input type="text" name="' . $this->prefix . $customField['name'] . '" id="' . $this->prefix . $customField['name'] . '" value="' . $value . '" disabled /></p>';
+            }
+            $default_ttl = get_option($this->prefix . 'ttl');
+            if ($customField['description']) echo '<p>' . sprintf($customField['description'], $default_ttl) . '</p>';
+        }
     }
 
     public function check_if_purgeable()
@@ -249,12 +275,20 @@
 
     public function purge_message()
     {
-        echo '<div id="message" class="updated fade"><p><strong>' . __('Varnish message:', $this->plugin) . '</strong><br />' . $this->noticeMessage . '</p></div>';
+        echo '<div id="message" class="updated fade"><p><strong>' . __('Varnish Caching', $this->plugin) . '</strong><br /><br />' . $this->noticeMessage . '</p></div>';
     }
 
     public function purge_message_no_ips()
     {
         echo '<div id="message" class="error fade"><p><strong>' . __('Please set the IPs for Varnish!', $this->plugin) . '</strong></p></div>';
+    }
+
+    public function purge_post_page()
+    {
+        if (isset($_SESSION['vcaching_note'])) {
+            echo '<div id="message" class="updated fade"><p><strong>' . __('Varnish Caching', $this->plugin) . '</strong><br /><br />' . $_SESSION['vcaching_note'] . '</p></div>';
+            unset ($_SESSION['vcaching_note']);
+        }
     }
 
     public function pretty_permalinks_message()
@@ -279,6 +313,7 @@
         $url = wp_nonce_url(admin_url('?' . $this->getParam), $this->plugin);
         $button = '';
         $nopermission = '';
+        $intro = '';
         if ($this->varnishIp == null) {
             $intro .= sprintf(__('Please setup Varnish IPs to be able to use <a href="%1$s">Varnish Caching</a>.', $this->plugin), 'http://wordpress.org/plugins/varnish-caching/');
         } else {
@@ -294,10 +329,11 @@
         } else {
             $text = $intro . ' ' . $nopermission;
         }
-        echo '<p class="varnish-galce">' . $text . '</p>';
-    }
-
-    protected function getRegisterEvents() {
+        echo '<p class="varnish-glance">' . $text . '</p>';
+    }
+
+    protected function get_register_events()
+    {
         $actions = array(
             'save_post',
             'deleted_post',
@@ -309,22 +345,27 @@
         return apply_filters('vcaching_events', $actions);
     }
 
-    public function purgeCache() {
+    public function purge_cache()
+    {
         $purgeUrls = array_unique($this->purgeUrls);
 
         if (empty($purgeUrls)) {
-            if (isset($_GET[$this->getParam]) && current_user_can('manage_options') && check_admin_referer($this->plugin)) {
-                $this->purgeUrl(home_url() .'/?vc-regex');
+            if (isset($_GET[$this->getParam]) && $this->check_if_purgeable() && check_admin_referer($this->plugin)) {
+                $this->purge_url(home_url() .'/?vc-regex');
             }
         } else {
             foreach($purgeUrls as $url) {
-                $this->purgeUrl($url);
-            }
+                $this->purge_url($url);
+            }
+        }
+        if ($this->truncateNotice) {
+            $this->noticeMessage .= '<br />' . __('Truncate message activated. Showing only first 3 messages.', $this->plugin);
         }
         add_action('admin_notices' , array($this, 'purge_message'));
     }
 
-    protected function purgeUrl($url) {
+    protected function purge_url($url)
+    {
         $p = parse_url($url);
 
         if (isset($p['query']) && ($p['query'] == 'vc-regex')) {
@@ -358,7 +399,7 @@
                     }
                 }
             } else {
-                if ($this->truncateNotice && $key <= 2 || $this->truncateNotice == false) {
+                if ($this->truncateNotice && $this->truncateCount <= 2 || $this->truncateNotice == false) {
                     $this->noticeMessage .= '' . __('Trying to purge URL :', $this->plugin) . $purgeme;
                     preg_match("/<title>(.*)<\/title>/i", $response['body'], $matches);
                     $this->noticeMessage .= ' => <br /> ' . isset($matches[1]) ? " => " . $matches[1] : $response['body'];
@@ -367,13 +408,11 @@
                         $this->noticeMessage .= $response['body'] . "<br />";
                     }
                 }
-            }
-        }
-        if ($this->truncateNotice) {
-            $this->noticeMessage .= '<br />' . __('Truncate message activated. Showing only first 3 messages.', $this->plugin);
-        }
-
-        do_action('after_purge_url', $url, $purgeme);
+                $this->truncateCount++;
+            }
+        }
+
+        do_action('vcaching_after_purge_url', $url, $purgeme);
     }
 
     public function purge_post($postId)
@@ -414,7 +453,7 @@
 
             // Archives and their feeds
             $archiveurls = array();
-            if ( get_post_type_archive_link(get_post_type($postId)) == true) {
+            if (get_post_type_archive_link(get_post_type($postId)) == true) {
                 array_push($listofurls,
                     get_post_type_archive_link( get_post_type($postId)),
                     get_post_type_archive_feed_link( get_post_type($postId))
@@ -436,8 +475,13 @@
 
             // Home Page and (if used) posts page
             array_push($listofurls, home_url('/'));
-            if ( get_option('show_on_front') == 'page') {
+            if (get_option('show_on_front') == 'page') {
                 array_push($listofurls, get_permalink(get_option('page_for_posts')));
+            }
+
+            // If Automattic's AMP is installed, add AMP permalink
+            if (function_exists('amp_get_permalink')) {
+                array_push($listofurls, amp_get_permalink($postId));
             }
 
             // Now flush all the URLs we've collected
@@ -449,7 +493,7 @@
         // @param array $purgeUrls the urls (paths) to be purged
         // @param int $postId the id of the new/edited post
         $this->purgeUrls = apply_filters('vcaching_purge_urls', $this->purgeUrls, $postId);
-        $this->purgeCache();
+        $this->purge_cache();
     }
 
     public function send_headers()
@@ -464,7 +508,7 @@
                 $ttl = get_option($this->prefix . 'ttl');
             }
             Header('X-VC-TTL: ' . $ttl, true);
-            if ($debug = get_option($this->prefix . 'debug')) {
+            if ($this->debug) {
                 Header('X-VC-Debug: true', true);
             }
         } else {
@@ -489,7 +533,9 @@
         add_action('admin_menu', array($this, 'add_menu_item'));
         add_action('admin_init', array($this, 'options_page_fields'));
         add_action('admin_init', array($this, 'console_page_fields'));
-        add_action('admin_init', array($this, 'conf_page_fields'));
+        if ($this->vclGeneratorTab) {
+            add_action('admin_init', array($this, 'conf_page_fields'));
+        }
     }
 
     public function add_menu_item()
@@ -511,7 +557,9 @@
                 <a class="nav-tab <?php if($_GET['tab'] == 'console'): ?>nav-tab-active<?php endif; ?>" href="<?php echo admin_url() ?>index.php?page=<?=$this->plugin?>-plugin&amp;tab=console"><?=__('Console', $this->plugin)?></a>
             <?php endif; ?>
             <a class="nav-tab <?php if($_GET['tab'] == 'stats'): ?>nav-tab-active<?php endif; ?>" href="<?php echo admin_url() ?>index.php?page=<?=$this->plugin?>-plugin&amp;tab=stats"><?=__('Statistics', $this->plugin)?></a>
-            <a class="nav-tab <?php if($_GET['tab'] == 'conf'): ?>nav-tab-active<?php endif; ?>" href="<?php echo admin_url() ?>index.php?page=<?=$this->plugin?>-plugin&amp;tab=conf"><?=__('Varnish VCLs', $this->plugin)?></a>
+            <?php if ($this->vclGeneratorTab): ?>
+                <a class="nav-tab <?php if($_GET['tab'] == 'conf'): ?>nav-tab-active<?php endif; ?>" href="<?php echo admin_url() ?>index.php?page=<?=$this->plugin?>-plugin&amp;tab=conf"><?=__('VCLs Generator', $this->plugin)?></a>
+            <?php endif; ?>
         </h2>
 
         <?php if(!isset($_GET['tab']) || $_GET['tab'] == 'options'): ?>
@@ -662,7 +710,7 @@
         add_settings_field($this->prefix . "truncate_notice", __("Truncate notice message", $this->plugin), array($this, $this->prefix . "truncate_notice"), $this->prefix . 'options', $this->prefix . 'options');
         add_settings_field($this->prefix . "debug", __("Enable debug", $this->plugin), array($this, $this->prefix . "debug"), $this->prefix . 'options', $this->prefix . 'options');
 
-        if($_POST['option_page'] == $this->prefix . 'options') {
+        if(isset($_POST['option_page']) && $_POST['option_page'] == $this->prefix . 'options') {
             register_setting($this->prefix . 'options', $this->prefix . "enable");
             register_setting($this->prefix . 'options', $this->prefix . "ttl");
             register_setting($this->prefix . 'options', $this->prefix . "homepage_ttl");
@@ -741,7 +789,7 @@
     public function varnish_caching_purge_key()
     {
         ?>
-            <input type="text" name="varnish_caching_purge_key" id="varnish_caching_purge_key" size="100" value="<?php echo get_option($this->prefix . 'purge_key'); ?>" />
+            <input type="text" name="varnish_caching_purge_key" id="varnish_caching_purge_key" size="100" maxlength="64" value="<?php echo get_option($this->prefix . 'purge_key'); ?>" />
             <span onclick="generateHash(64, 0, 'varnish_caching_purge_key'); return false;" class="dashicons dashicons-image-rotate" title="<?=__('Generate')?>"></span>
             <p class="description">
                 <?=__('Key used to purge Varnish cache. It is sent to Varnish as X-VC-Purge-Key header. Use a SHA-256 hash.<br />If you can\'t use ACL\'s, use this option. You can set the `purge key` in lib/purge.vcl.<br />Search the default value ff93c3cb929cee86901c7eefc8088e9511c005492c6502a930360c02221cf8f4 to find where to replace it.', $this->plugin)?>
@@ -752,10 +800,10 @@
     public function varnish_caching_cookie()
     {
         ?>
-            <input type="text" name="varnish_caching_cookie" id="varnish_caching_cookie" size="10" maxlength="10" value="<?php echo get_option($this->prefix . 'cookie'); ?>" />
-            <span onclick="generateHash(10, 0, 'varnish_caching_cookie'); return false;" class="dashicons dashicons-image-rotate" title="<?=__('Generate')?>"></span>
+            <input type="text" name="varnish_caching_cookie" id="varnish_caching_cookie" size="100" maxlength="64" value="<?php echo get_option($this->prefix . 'cookie'); ?>" />
+            <span onclick="generateHash(64, 0, 'varnish_caching_cookie'); return false;" class="dashicons dashicons-image-rotate" title="<?=__('Generate')?>"></span>
             <p class="description">
-                <?=__('This module sets a special cookie to tell Varnish that the user is logged in. This should be a random 10 chars string [0-9a-z]. You can set the `logged in cookie` in default.vcl.<br />Search the default value <i>c005492c65</i> to find where to replace it.', $this->plugin)?>
+                <?=__('This module sets a special cookie to tell Varnish that the user is logged in. Use a SHA-256 hash. You can set the `logged in cookie` in default.vcl.<br />Search the default value <i>flxn34napje9kwbwr4bjwz5miiv9dhgj87dct4ep0x3arr7ldif73ovpxcgm88vs</i> to find where to replace it.', $this->plugin)?>
             </p>
         <?php
     }
@@ -812,7 +860,7 @@
         add_settings_field($this->prefix . "varnish_backends", __("Backends", $this->plugin), array($this, $this->prefix . "varnish_backends"), $this->prefix . 'conf', "conf");
         add_settings_field($this->prefix . "varnish_acls", __("ACLs", $this->plugin), array($this, $this->prefix . "varnish_acls"), $this->prefix . 'conf', "conf");
 
-        if($_POST['option_page'] == $this->prefix . 'conf') {
+        if(isset($_POST['option_page']) && $_POST['option_page'] == $this->prefix . 'conf') {
             register_setting($this->prefix . 'conf', $this->prefix . "varnish_backends");
             register_setting($this->prefix . 'conf', $this->prefix . "varnish_acls");
         }
@@ -824,7 +872,7 @@
 
         add_settings_field($this->prefix . "varnish_version", __("Version", $this->plugin), array($this, $this->prefix . "varnish_version"), $this->prefix . 'download', "download");
 
-        if($_POST['option_page'] == $this->prefix . 'download') {
+        if(isset($_POST['option_page']) && $_POST['option_page'] == $this->prefix . 'download') {
             $version = in_array($_POST['varnish_caching_varnish_version'], array(3,4)) ? $_POST['varnish_caching_varnish_version'] : 3;
             $tmpfile = tempnam("tmp", "zip");
             $zip = new ZipArchive();
@@ -894,7 +942,7 @@
     {
         if ($file == 'default.vcl') {
             $logged_in_cookie = get_option($this->prefix . 'cookie');
-            $content = str_replace('c005492c65', $logged_in_cookie, $content);
+            $content = str_replace('flxn34napje9kwbwr4bjwz5miiv9dhgj87dct4ep0x3arr7ldif73ovpxcgm88vs', $logged_in_cookie, $content);
         } else if ($file == 'conf/backend.vcl') {
             if ($version == 3) {
                 $content = "";
@@ -959,12 +1007,32 @@
         }
         return $content;
     }
+
+    public function post_row_actions($actions, $post)
+    {
+        if ($this->check_if_purgeable()) {
+            $actions = array_merge($actions, array(
+                'vcaching_purge_post' => sprintf('<a href="%s">' . __('Purge from Varnish', $this->plugin) . '</a>', wp_nonce_url(sprintf('admin.php?page=vcaching-plugin&tab=console&action=purge_post&post_id=%d', $post->ID), $this->plugin))
+            ));
+        }
+        return $actions;
+    }
+
+    public function page_row_actions($actions, $post)
+    {
+        if ($this->check_if_purgeable()) {
+            $actions = array_merge($actions, array(
+                'vcaching_purge_page' => sprintf('<a href="%s">' . __('Purge from Varnish', $this->plugin) . '</a>', wp_nonce_url(sprintf('admin.php?page=vcaching-plugin&tab=console&action=purge_page&post_id=%d', $post->ID), $this->plugin))
+            ));
+        }
+        return $actions;
+    }
 }
 
 $vcaching = new VCaching();
 
 // WP-CLI
-if ( defined('WP_CLI') && WP_CLI ) {
+if (defined('WP_CLI') && WP_CLI) {
     include('wp-cli.php');
 }
 

comments