Exemplo n.º 1
0
 public static function purge_varnish_cache($post_id = null)
 {
     global $wpengine_platform_config;
     global $wpe_varnish_servers;
     global $wpdb;
     $wpe_all_domains = $wpengine_platform_config['all_domains'];
     if (!$wpe_all_domains) {
         $wpe_all_domains = array();
     }
     static $purge_counter;
     // Globally disabled?
     if (defined('WPE_DISABLE_CACHE_PURGING') && WPE_DISABLE_CACHE_PURGING) {
         return false;
     }
     // Autosaving never updates published content.
     if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
         return false;
     }
     // If we've purged "enough" times, stop already.
     if (isset($purge_counter) && $purge_counter > 2) {
         return false;
     }
     $blog_url = home_url();
     $blog_url_parts = @parse_url($blog_url);
     $blog_domain = $blog_url_parts['host'];
     // If purging everything, $paths and $abspaths are empty.
     $abspaths = array();
     // paths to purge exactly; no prefix or suffixes.
     $paths = array();
     // path regular expressions to purge.
     $purge_thing = false;
     if ($post_id && $post_id > 1 && !!($post = get_post($post_id))) {
         // Certain post types aren't cached so we shouldn't purge
         if ($post->post_type == 'attachment' || $post->post_type == 'revision') {
             return;
         }
         // If the post isn't published, we don't need to purge (draft, scheduled, deleted)
         if ($post->post_status != 'publish') {
             //error_log("purgebail: ".$post->post_status);
             return;
         }
         //error_log("micropurge: $post_id");
         // Determine the set of paths to purge.  If there's no post_id, purge all. Otherwise name the paths.
         $purge_domains = array($blog_domain);
         $blog_path = WpeCommon::get_path_trailing_slash(@$blog_url_parts['path']);
         if ($blog_path == '/') {
             $blog_path_prefix = "";
         } else {
             $tpath = substr($blog_path, 0, -1);
             $blog_path_prefix = $tpath . ".*";
         }
         // Always purge the post's own URI, along with anything similar
         $post_parts = parse_url(post_permalink($post_id));
         $post_uri = rtrim($post_parts['path'], '/') . "(.*)";
         if (!empty($post_parts['query'])) {
             $post_uri .= "?" . $post_parts['query'];
         }
         $paths[] = $post_uri;
         // Purge the categories & tags this post belongs to
         if (defined('WPE_PURGE_CATS_ON_PUB')) {
             foreach (wp_get_post_categories($post_id) as $cat_id) {
                 $cat = get_category($cat_id);
                 $slug = $cat->slug;
                 $paths[] = "{$blog_path_prefix}/{$slug}/";
             }
             foreach (wp_get_post_tags($post_id) as $tag) {
                 $slug = $tag->slug;
                 $paths[] = "{$blog_path_prefix}/{$slug}/";
             }
         }
         // Purge main pages if we're there.  Can't know for sure, so approximate by saying
         // if it's more than 7 days old it's either not there or has been there for so
         // long that it doesn't matter.
         if (time() - strtotime($post->post_date_gmt) < 60 * 60 * 24 * 7) {
             if ($post->post_type != 'shop_order') {
                 $paths[] = "^{$blog_path}\$";
                 $paths[] = "/feed";
             }
         }
         $purge_thing = $post_id;
     } else {
         $paths[] = ".*";
         // full blog purge
         $purge_thing = true;
         $purge_domains = $wpe_all_domains;
         if (isset($wpdb->dmtable)) {
             $rows = $wpdb->get_results("SELECT domain FROM {$wpdb->dmtable}");
             foreach ($rows as $row) {
                 $purge_domains[] = strtolower($row->domain);
             }
             $purge_domains = array_unique($purge_domains);
         }
     }
     // add on blog domains for this blog
     // this will ensure we are purging in all proper locations
     $purge_domains = array_unique(array_merge($purge_domains, self::get_blog_domains()));
     if (!count($paths)) {
         return;
         // short-circuit if there's nothing to do.
     }
     // else:
     $paths = array_unique($paths);
     // allow the code above to be sloppy
     // At this point, we know we're going to purge, so let's bump the purge counter. This will prevent us from
     // over-purging on a given request.
     // BWD: I'm not sure this is necessary and may actually be harmful, depending on how many updates to a given
     // post can happen within a single request.
     if (!isset($purge_counter)) {
         $purge_counter = 1;
     } else {
         $purge_counter++;
     }
     // Purge Varnish cache.
     if (WPE_CLUSTER_TYPE == "pod") {
         $wpe_varnish_servers = array("localhost");
     } else {
         if (!isset($wpe_varnish_servers)) {
             if (!defined('WPE_CLUSTER_ID') || !WPE_CLUSTER_ID) {
                 $lbmaster = "lbmaster";
             } else {
                 if (WPE_CLUSTER_ID >= 4) {
                     $lbmaster = "localhost";
                     // so the current user sees the purge
                 } else {
                     $lbmaster = "lbmaster-" . WPE_CLUSTER_ID;
                 }
             }
             $wpe_varnish_servers = array($lbmaster);
         }
     }
     // Debugging
     if (false) {
         $msg_key = rand();
         $msg = "Varnishes # {$msg_key}:\n" . var_export($wpe_varnish_servers, true) . "\nDomains:\n" . var_export($purge_domains, true) . "\nPaths:\n" . var_export($paths, true);
         //error_log( "PURGE: $msg" );
     }
     if ($paths) {
         $paths_regex = '(' . join('|', $paths) . ')';
     }
     if ($abspaths) {
         $abspaths = array_map('preg_quote', $abspaths);
         $abspaths_regex = '^(' . join('|', $abspaths) . ')$';
     }
     if ($paths && $abspaths) {
         $path_regex = "(({$abspaths_regex})|({$paths_regex}))";
     } else {
         if ($paths) {
             $path_regex = $paths_regex;
         } else {
             if ($abspaths) {
                 $path_regex = $abspaths_regex;
             } else {
                 $path_regex = '.*';
             }
         }
     }
     // Convert the purge domains to PCRE-escaped strings and join them together in an alternation -- purging in
     // blocks of 100 domains. Varnish can't handle an unlimited number. Ordinarily, this will still be one chunk,
     // but for some massive sites, there can be more than 100 domains mapped, unfortunately.
     $hostname = $purge_domains[0];
     $purge_domains = array_map('preg_quote', $purge_domains);
     $purge_domain_chunks = array_chunk($purge_domains, 100);
     foreach ($purge_domain_chunks as $chunk) {
         $purge_domain_regex = '^(' . join('|', $chunk) . ')$';
         // Tell Varnish.
         foreach ($wpe_varnish_servers as $varnish) {
             $headers = array('X-Purge-Path' => $path_regex, 'X-Purge-Host' => $purge_domain_regex);
             $ok = WpeCommon::http_request_async('PURGE', $varnish, 9002, $hostname, '/', $headers, 0);
             if (!$ok) {
                 error_log("purge_varnish_cache() failed for: ({$varnish}) #{$purge_domain_regex}# #{$path_regex}#");
             }
         }
     }
     return true;
 }
Exemplo n.º 2
0
 public static function purge_varnish_cache($post_id = null)
 {
     global $wpe_all_domains;
     static $purge_counter;
     global $wpe_varnish_servers, $wpe_ec_servers;
     global $wpdb;
     // Globally disabled?
     if (WPE_DISABLE_CACHE_PURGING) {
         return false;
     }
     // If already done, don't keep harping on it.
     if (isset($purge_counter) && $purge_counter > 2) {
         return false;
     }
     $blog_url = home_url();
     $blog_url_parts = @parse_url($blog_url);
     $blog_domain = $blog_url_parts['host'];
     $paths = array();
     // will leave empty if we want a purge-all
     $purge_thing = false;
     if ($post_id && $post_id > 1 && !!($post = get_post($post_id))) {
         //error_log("micropurge: $post_id");
         // Determine the set of paths to purge.  If there's no post_id, purge all. Otherwise name the paths.
         $purge_domains = array($blog_domain);
         $blog_path = WpeCommon::get_path_trailing_slash(@$blog_url_parts['path']);
         if ($blog_path == '/') {
             $blog_path_prefix = "";
         } else {
             $tpath = substr($blog_path, 0, -1);
             $blog_path_prefix = $tpath . ".*";
         }
         // Certain post types aren't cached so we shouldn't purge
         if ($post->post_type == 'attachment' || $post->post_type == 'revision') {
             return;
         }
         // If the post isn't published, we don't need to purge (draft, scheduled, deleted)
         if ($post->post_status != 'publish') {
             //error_log("purgebail: ".$post->post_status);
             return;
         }
         // Always purge the post's own URI, along with anything similar
         $post_parts = parse_url(post_permalink($post_id));
         $post_uri = rtrim($post_parts['path'], '/') . "(.*)";
         if (!empty($post_parts['query'])) {
             $post_uri .= "?" . $post_parts['query'];
         }
         $paths[] = $post_uri;
         // Purge the categories & tags this post belongs to
         if (defined('WPE_PURGE_CATS_ON_PUB')) {
             foreach (wp_get_post_categories($post_id) as $cat_id) {
                 $cat = get_category($cat_id);
                 $slug = $cat->slug;
                 $paths[] = "{$blog_path_prefix}/{$slug}/";
             }
             foreach (wp_get_post_tags($post_id) as $tag) {
                 $slug = $tag->slug;
                 $paths[] = "{$blog_path_prefix}/{$slug}/";
             }
         }
         // Purge main pages if we're there.  Can't know for sure, so approximate by saying
         // if it's more than 7 days old it's either not there or has been there for so
         // long that it doesn't matter.
         if (time() - strtotime($post->post_date_gmt) < 60 * 60 * 24 * 7) {
             $paths[] = "{$blog_path}=";
             $paths[] = "/feed";
         }
         $purge_thing = $post_id;
     } else {
         $paths[] = "/*";
         // full blog purge
         $purge_thing = true;
         $purge_domains = $wpe_all_domains;
         if (isset($wpdb->dmtable)) {
             $rows = $wpdb->get_results("SELECT domain FROM {$wpdb->dmtable}");
             foreach ($rows as $row) {
                 $purge_domains[] = strtolower($row->domain);
             }
             $purge_domains = array_unique($purge_domains);
         }
     }
     if (!count($paths)) {
         return;
     }
     // short-circuit if there's nothing to do.
     $paths = array_unique($paths);
     // allow the code above to be sloppy
     // If we've already purged on this web-request, don't do it again.
     // DO NOT RUN THIS at the TOP of the method because it's possible the post-status changed in the middle!
     //error_log("micropurge: $post_id, already=$already_purged_all_varnish, ".var_export($paths));
     if (!isset($purge_counter)) {
         $purge_counter = 1;
     } else {
         $purge_counter++;
     }
     // Determine the set of domains to purge against.
     // If there's a huge number of domains, only purge the current domain.
     if (count($wpe_all_domains) > 8) {
         $purge_domains = array($blog_domain);
     }
     // Purge Varnish cache.
     if (WPE_CLUSTER_TYPE == "pod") {
         $wpe_varnish_servers = array("localhost");
     } else {
         if (!isset($wpe_varnish_servers)) {
             if (!defined('WPE_CLUSTER_ID') || !WPE_CLUSTER_ID) {
                 $lbmaster = "lbmaster";
             } else {
                 if (WPE_CLUSTER_ID >= 4) {
                     $lbmaster = "localhost";
                 } else {
                     $lbmaster = "lbmaster-" . WPE_CLUSTER_ID;
                 }
             }
             $wpe_varnish_servers = array($lbmaster);
         }
     }
     // Debugging
     if (false) {
         $msg_key = rand();
         $msg = "Varnishes # {$msg_key}:\n" . var_export($wpe_varnish_servers, true) . "\nDomains:\n" . var_export($purge_domains, true) . "\nPaths:\n" . var_export($paths, true);
         //error_log( "PURGE: $msg" );
     }
     // Tell Varnish, unless we're using EC
     if (!isset($wpe_ec_servers) || count($wpe_ec_servers) == 0) {
         foreach ($wpe_varnish_servers as $varnish) {
             $purge_fails = array();
             foreach ($purge_domains as $hostname) {
                 foreach ($paths as $path) {
                     //error_log("####: $varnish: $hostname, $path");
                     $ok = WpeCommon::http_request_async("PURGE", $varnish, 9002, $hostname, $path, array(), 0);
                     if (!$ok) {
                         $purge_fails[] = "({$varnish}){$hostname}{$path}";
                     }
                 }
             }
             if (count($purge_fails) > 0) {
                 error_log("purge_varnish_cache() failed for: " . implode(", ", $purge_fails));
             }
         }
     }
     // Tell EC, if we're using it
     /*
     if ( isset($wpe_ec_servers) ) foreach ( $wpe_ec_servers as $ec ) {
     	WpeCommon::http_request_async( "GET", $ec, 9003, $_SERVER['HTTP_HOST'], '/', array(
     		'X-EC-Command' => 'purge',
     		'X-EC-Domains' => join('|',$purge_domains),
     		'X-EC-Uris' => join('|',$paths),
     	), 0 );
     }
     */
     return true;
 }