Path : /home/vishqocm/vishalwebtech.in/blog/wp-content/themes/katerio/functions/
File Upload :
Current File : /home/vishqocm//vishalwebtech.in//blog/wp-content/themes/katerio/functions/wp-helper.php

<?php
/**
 * This file contains a bunch of helper functions that handle add caching to core WordPress functions.
 */

/**
 * Cached version of get_category_by_slug.
 *
 * @param  string $slug Category slug
 * @return object|null|bool Term Row from database. Will return null if $slug doesn't match a term. If taxonomy does not exist then false will be returned.
 * @link   http://vip.wordpress.com/documentation/uncached-functions/ Uncached Functions
 */
function _th90_get_category_by_slug( $slug )
{
    return _th90_get_term_by('slug', $slug, 'category');
}

/**
 * Cached version of get_term_by.
 *
 * Many calls to get_term_by (with name or slug lookup) across on a single pageload can easily add up the query count.
 * This function helps prevent that by adding a layer of caching.
 *
 * @param  string     $field    Either 'slug', 'name', or 'id'
 * @param  string|int $value    Search for this term value
 * @param  string     $taxonomy Taxonomy Name
 * @param  string     $output   Optional. Constant OBJECT, ARRAY_A, or ARRAY_N
 * @param  string     $filter   Optional. Default is 'raw' or no WordPress defined filter will applied.
 * @return mixed|null|bool Term Row from database in the type specified by $filter. Will return false if $taxonomy does not exist or $term was not found.
 * @link   http://vip.wordpress.com/documentation/uncached-functions/ Uncached Functions
 */
function _th90_get_term_by( $field, $value, $taxonomy, $output = OBJECT, $filter = 'raw' )
{
    // ID lookups are cached
    if ('id' === $field ) {
        return get_term_by($field, $value, $taxonomy, $output, $filter);
    }

    $cache_key = $field . '|' . $taxonomy . '|' . md5($value);
    $term_id = wp_cache_get($cache_key, 'get_term_by');

    if (false === $term_id ) {
        $term = get_term_by($field, $value, $taxonomy);
        if ($term && ! is_wp_error($term) ) {
            wp_cache_set($cache_key, $term->term_id, 'get_term_by', 4 * HOUR_IN_SECONDS);
        } else {
            wp_cache_set($cache_key, 0, 'get_term_by', 15 * MINUTE_IN_SECONDS); // if we get an invalid value, let's cache it anyway but for a shorter period of time
        }
    } else {
        $term = get_term($term_id, $taxonomy, $output, $filter);
    }

    if (is_wp_error($term) ) {
        $term = false;
    }

    return $term;
}

/**
 * Properly clear _th90_get_term_by() cache when a term is updated
 */
add_action('edit_terms', 'wp_flush_get_term_by_cache', 10, 2);
add_action('create_term', 'wp_flush_get_term_by_cache', 10, 2);
function wp_flush_get_term_by_cache( $term_id, $taxonomy )
{
    $term = get_term_by('id', $term_id, $taxonomy);
    if (! $term ) {
        return;
    }
    foreach ( array( 'name', 'slug' ) as $field ) {
        $cache_key = $field . '|' . $taxonomy . '|' . md5($term->$field);
        $cache_group = 'get_term_by';
        wp_cache_delete($cache_key, $cache_group);
    }
}

/**
 * Cached version of term_exists()
 *
 * Term exists calls can pile up on a single pageload.
 * This function adds a layer of caching to prevent lots of queries.
 *
 * @param  int|string $term     The term to check can be id, slug or name.
 * @param  string     $taxonomy The taxonomy name to use
 * @param  int        $parent   Optional. ID of parent term under which to confine the exists search.
 * @return mixed Returns null if the term does not exist. Returns the term ID
 *               if no taxonomy is specified and the term ID exists. Returns
 *               an array of the term ID and the term taxonomy ID the taxonomy
 *               is specified and the pairing exists.
 */

function _th90_term_exists( $term, $taxonomy = '', $parent = null )
{
    // If $parent is not null, let's skip the cache.
    if (null !== $parent ) {
        return term_exists($term, $taxonomy, $parent);
    }

    if (! empty($taxonomy) ) {
        $cache_key = $term . '|' . $taxonomy;
    } else {
        $cache_key = $term;
    }

    $cache_value = wp_cache_get($cache_key, 'term_exists');

    // term_exists frequently returns null, but (happily) never false
    if (false === $cache_value ) {
        $term_exists = term_exists($term, $taxonomy);
        wp_cache_set($cache_key, $term_exists, 'term_exists', 3 * HOUR_IN_SECONDS);
    } else {
        $term_exists = $cache_value;
    }

    if (is_wp_error($term_exists) ) {
        $term_exists = null;
    }

    return $term_exists;
}

/**
 * Properly clear _th90_term_exists() cache when a term is updated
 */
add_action('delete_term', 'wp_flush_term_exists', 10, 4);
function wp_flush_term_exists( $term, $tt_id, $taxonomy, $deleted_term )
{
    foreach ( array( 'term_id', 'name', 'slug' ) as $field ) {
        $cache_key = $deleted_term->$field . '|' . $taxonomy ;
        $cache_group = 'term_exists';
        wp_cache_delete($cache_key, $cache_group);
    }
}

/**
 * Optimized version of get_term_link that adds caching for slug-based lookups.
 *
 * Returns permalink for a taxonomy term archive, or a WP_Error object if the term does not exist.
 *
 * @param int|string|object $term     The term object / term ID / term slug whose link will be retrieved.
 * @param string            $taxonomy The taxonomy slug. NOT required if you pass the term object in the first parameter
 *
 * @return string|WP_Error HTML link to taxonomy term archive on success, WP_Error if term does not exist.
 */
function _th90_get_term_link( $term, $taxonomy = null )
{
    // ID- or object-based lookups already result in cached lookups, so we can ignore those.
    if (is_numeric($term) || is_object($term) ) {
        return get_term_link($term, $taxonomy);
    }

    $term_object = _th90_get_term_by('slug', $term, $taxonomy);
    return get_term_link($term_object);
}

/**
 * Cached version of get_page_by_title so that we're not making unnecessary SQL all the time
 *
 * @param  string $page_title Page title
 * @param  string $output     Optional. Output type; OBJECT*, ARRAY_N, or ARRAY_A.
 * @param  string $post_type  Optional. Post type; default is 'page'.
 * @return WP_Post|null WP_Post on success or null on failure
 * @link   http://vip.wordpress.com/documentation/uncached-functions/ Uncached Functions
 */
function _th90_get_page_by_title( $title, $output = OBJECT, $post_type = 'page' )
{
    $cache_key = $post_type . '_' . sanitize_key($title);
    $page_id = wp_cache_get($cache_key, 'get_page_by_title');

    if (false === $page_id ) {
        $page = get_page_by_title($title, OBJECT, $post_type);
        $page_id = $page ? $page->ID : 0;
        wp_cache_set($cache_key, $page_id, 'get_page_by_title', 3 * HOUR_IN_SECONDS); // We only store the ID to keep our footprint small
    }

    if ($page_id ) {
        return get_page($page_id, $output);
    }

    return null;
}

/**
 * Cached version of get_page_by_path so that we're not making unnecessary SQL all the time
 *
 * @param  string $page_path Page path
 * @param  string $output    Optional. Output type; OBJECT*, ARRAY_N, or ARRAY_A.
 * @param  string $post_type Optional. Post type; default is 'page'.
 * @return WP_Post|null WP_Post on success or null on failure
 * @link   http://vip.wordpress.com/documentation/uncached-functions/ Uncached Functions
 */
function _th90_get_page_by_path( $page_path, $output = OBJECT, $post_type = 'page' )
{
    if (is_array($post_type) ) {
        $cache_key = sanitize_key($page_path) . '_' . md5(serialize($post_type));
    } else {
        $cache_key = $post_type . '_' . sanitize_key($page_path);
    }

    $page_id = wp_cache_get($cache_key, 'get_page_by_path');

    if (false === $page_id ) {
        $page = get_page_by_path($page_path, $output, $post_type);
        $page_id = $page ? $page->ID : 0;
        if (0 === $page_id ) {
            wp_cache_set($cache_key, $page_id, 'get_page_by_path', ( 1 * HOUR_IN_SECONDS + mt_rand(0, HOUR_IN_SECONDS) )); // We only store the ID to keep our footprint small
        } else {
            wp_cache_set($cache_key, $page_id, 'get_page_by_path', 0); // We only store the ID to keep our footprint small
        }
    }

    if ($page_id ) {
        return get_page($page_id, $output);
    }

    return null;
}

/**
 * Flush the cache for published pages so we don't end up with stale data
 *
 * @param string  $new_status The post's new status
 * @param string  $old_status The post's previous status
 * @param WP_Post $post       The post
 * @link  http://vip.wordpress.com/documentation/uncached-functions/ Uncached Functions
 */
function _th90_flush_get_page_by_title_cache( $new_status, $old_status, $post )
{
    if ('publish' === $new_status || 'publish' === $old_status ) {
        wp_cache_delete($post->post_type . '_' . sanitize_key($post->post_title), 'get_page_by_title');
    }
}
add_action('transition_post_status', '_th90_flush_get_page_by_title_cache', 10, 3);

/**
 * Flush the cache for published pages so we don't end up with stale data
 *
 * @param string  $new_status The post's new status
 * @param string  $old_status The post's previous status
 * @param WP_Post $post       The post
 *
 * @link http://vip.wordpress.com/documentation/uncached-functions/ Uncached Functions
 */
function _th90_flush_get_page_by_path_cache( $new_status, $old_status, $post )
{
    if ('publish' === $new_status || 'publish' === $old_status ) {
        $page_path = get_page_uri($post->ID);
        wp_cache_delete($post->post_type . '_' . sanitize_key($page_path), 'get_page_by_path');
    }
}
add_action('transition_post_status', '_th90_flush_get_page_by_path_cache', 10, 3);

/**
 * Cached version of url_to_postid, which can be expensive.
 *
 * Examine a url and try to determine the post ID it represents.
 *
 * @param  string $url Permalink to check.
 * @return int Post ID, or 0 on failure.
 */
function _th90_url_to_postid( $url )
{
    // Can only run after init, since home_url() has not been filtered to the mapped domain prior to that,
    // which will cause url_to_postid to fail
    // @see https://vip.wordpress.com/documentation/vip-development-tips-tricks/home_url-vs-site_url/
    if (! did_action('init') ) {
        _doing_it_wrong('_th90_url_to_postid', '_th90_url_to_postid must be called after the init action, as home_url() has not yet been filtered', '');

        return 0;
    }

    // Sanity check; no URLs not from this site
    if (parse_url($url, PHP_URL_HOST) !== _th90_get_home_host() ) {
        return 0;
    }

    $cache_key = md5($url);
    $post_id = wp_cache_get($cache_key, 'url_to_postid');

    if (false === $post_id ) {
        $post_id = url_to_postid($url); // returns 0 on failure, so need to catch the false condition
        wp_cache_set($cache_key, $post_id, 'url_to_postid', 3 * HOUR_IN_SECONDS);
    }

    return $post_id;
}

add_action(
    'transition_post_status', function ( $new_status, $old_status, $post ) {
        if ('publish' !== $new_status && 'publish' !== $old_status ) {
            return;
        }

        $url = get_permalink($post->ID);
        wp_cache_delete(md5($url), 'url_to_postid');
    }, 10, 3
);

/**
 * Cached version of wp_old_slug_redirect.
 *
 * Cache the results of the _wp_old_slug meta query, which can be expensive.
 *
 * @deprecated use _th90_wp_old_slug_redirect instead
 */
function _th90_old_slug_redirect()
{
    global $wp_query;
    if (is_404() && '' !== $wp_query->query_vars['name'] ) {
        global $wpdb;

        // Guess the current post_type based on the query vars.
        if (get_query_var('post_type') ) {
            $post_type = get_query_var('post_type');
        } elseif (! empty($wp_query->query_vars['pagename']) ) {
            $post_type = 'page';
        } else {
            $post_type = 'post';
        }

        if (is_array($post_type) ) {
            if (count($post_type) > 1 ) {
                return;
            }
            $post_type = array_shift($post_type);
        }

        // Do not attempt redirect for hierarchical post types
        if (is_post_type_hierarchical($post_type) ) {
            return;
        }

        $query = $wpdb->prepare("SELECT post_id FROM $wpdb->postmeta, $wpdb->posts WHERE ID = post_id AND post_type = %s AND meta_key = '_wp_old_slug' AND meta_value = %s", $post_type, $wp_query->query_vars['name']);

        // if year, monthnum, or day have been specified, make our query more precise
        // just in case there are multiple identical _wp_old_slug values
        if ('' !== $wp_query->query_vars['year'] ) {
            $query .= $wpdb->prepare(' AND YEAR(post_date) = %d', $wp_query->query_vars['year']);
        }
        if ('' !== $wp_query->query_vars['monthnum'] ) {
            $query .= $wpdb->prepare(' AND MONTH(post_date) = %d', $wp_query->query_vars['monthnum']);
        }
        if ('' !== $wp_query->query_vars['day'] ) {
            $query .= $wpdb->prepare(' AND DAYOFMONTH(post_date) = %d', $wp_query->query_vars['day']);
        }

        $cache_key = md5(serialize($query));

        if (false === $id = wp_cache_get($cache_key, 'wp_old_slug_redirect') ) {
            $id = (int) $wpdb->get_var($query);

            wp_cache_set($cache_key, $id, 'wp_old_slug_redirect', 5 * MINUTE_IN_SECONDS);
        }

        if (! $id ) {
            return;
        }

        $link = get_permalink($id);

        if (! $link ) {
            return;
        }

        wp_redirect($link, 301); // Permanent redirect
        exit;
    }
}


/**
 * Cached version of count_user_posts, which is uncached but doesn't always need to hit the db
 *
 * count_user_posts is generally fast, but it can be easy to end up with many redundant queries
 * if it's called several times per request. This allows bypassing the db queries in favor of
 * the cache
 */
function _th90_count_user_posts( $user_id )
{
    if (! is_numeric($user_id) ) {
        return 0;
    }

    $cache_key = 'vip_' . (int) $user_id;
    $cache_group = 'user_posts_count';

    if (false === ( $count = wp_cache_get($cache_key, $cache_group) ) ) {
        $count = count_user_posts($user_id);

        wp_cache_set($cache_key, $count, $cache_group, 5 * MINUTE_IN_SECONDS);
    }

    return $count;
}

/*
 * Cached version of wp_get_nav_menu_object
 *
 * Many calls to get_term_by (with name or slug lookup as used inside the wp_get_nav_menu_object) across on a single pageload can easily add up the query count.
 * This function helps prevent that by taking advantage of _th90_get_term_by function which adds a layer of caching.
 *
 * @param string $menu Menu ID, slug, or name.
 * @uses _th90_get_term_by
 * @return mixed false if $menu param isn't supplied or term does not exist, menu object if successful.
 */
function _th90_get_nav_menu_object( $menu )
{
    if (! $menu ) {
        return false;
    }

    $menu_obj = get_term($menu, 'nav_menu');

    if (! $menu_obj ) {
        $menu_obj = _th90_get_term_by('slug', $menu, 'nav_menu');
    }

    if (! $menu_obj ) {
        $menu_obj = _th90_get_term_by('name', $menu, 'nav_menu');
    }

    if (! $menu_obj ) {
        $menu_obj = false;
    }

    return $menu_obj;
}

/**
 * Require the Stampedeless_Cache class for use in our helper functions below.
 *
 * The Stampedeless_Cache helps prevent cache stampedes by internally varying the cache
 * expiration slightly when creating a cache entry in an effort to avoid multiple keys
 * expiring simultaneously and allowing a single request to regenerate the cache shortly
 * before it's expiration.
 */
if (function_exists('require_lib') && defined('WPCOM_IS_VIP_ENV') && WPCOM_IS_VIP_ENV ) {
    require_lib('class.stampedeless-cache');
}

/**
 * Drop in replacement for wp_cache_set().
 *
 * Wrapper for the WPCOM Stampedeless_Cache class.
 *
 * @param  string                  $key        Cache key.
 * @param  string|int|array|object $value      Data to store in the cache.
 * @param  string                  $group      Optional. Cache group.
 * @param  int                     $expiration Optional. Cache TTL in seconds.
 * @return bool This function always returns true.
 */
function _th90_cache_set( $key, $value, $group = '', $expiration = 0 )
{
    if (! class_exists('Stampedeless_Cache') ) {
        return wp_cache_set($key, $value, $group, $expiration);
    }

    $sc = new Stampedeless_Cache($key, $group);
    $sc->set($value, $expiration);

    return true;
}

/**
 * Drop in replacement for wp_cache_get().
 *
 * Wrapper for the WPCOM Stampedeless_Cache class.
 *
 * @param  string $key   Cache key.
 * @param  string $group Optional. Cache group.
 * @return mixed Returns false if failing to retrieve cache entry or the cached data otherwise.
 */
function _th90_cache_get( $key, $group = '' )
{
    if (! class_exists('Stampedeless_Cache') ) {
        return wp_cache_get($key, $group);
    }

    $sc = new Stampedeless_Cache($key, $group);

    return $sc->get();
}

/**
 * Drop in replacement for wp_cache_delete().
 *
 * Wrapper for WPCOM Stampedeless_Cache class.
 *
 * @param  string $key   Cache key.
 * @param  string $group Optional. Cache group.
 * @return bool True on successful removal, false on failure.
 */
function _th90_cache_delete( $key, $group = '' )
{
    // delete cache itself
    $deleted = wp_cache_delete($key, $group);

    if (class_exists('Stampedeless_Cache') ) {
        // delete lock
        $lock_key = $key . '_lock';
        wp_cache_delete($lock_key, $group);
    }

    return $deleted;
}

/**
 * Retrieve adjacent post.
 *
 * Can either be next or previous post. The logic for excluding terms is handled within PHP, for performance benefits.
 * Props to Elliott Stocks
 *
 * @global wpdb $wpdb
 *
 * @param bool   $in_same_term  Optional. Whether post should be in a same taxonomy term. Note - only the first term will be used from wp_get_object_terms().
 * @param int    $excluded_term Optional. The term to exclude.
 * @param bool   $previous      Optional. Whether to retrieve previous post.
 * @param string $taxonomy      Optional. Taxonomy, if $in_same_term is true. Default 'category'.
 *
 * @return null|string|WP_Post Post object if successful. Null if global $post is not set. Empty string if no corresponding post exists.
 */
function _th90_get_adjacent_post( $in_same_term = false, $excluded_terms = '', $previous = true, $taxonomy = 'category', $adjacent = '' )
{
    global $wpdb;
    if (( ! $post = get_post() ) || ! taxonomy_exists($taxonomy) ) {
        return null;
    }
    $join = '';
    $where = '';
    $current_post_date = $post->post_date;

    if ($in_same_term ) {
        if (is_object_in_taxonomy($post->post_type, $taxonomy) ) {
            $term_array = get_the_terms($post->ID, $taxonomy);
            if (! empty($term_array) && ! is_wp_error($term_array) ) {
                $term_array_ids = wp_list_pluck($term_array, 'term_id');
                // Remove any exclusions from the term array to include.
                $excluded_terms = explode(',', $excluded_terms);
                if (! empty($excluded_terms) ) {
                    $term_array_ids = array_diff($term_array_ids, (array) $excluded_terms);
                }
                if (! empty($term_array_ids) ) {
                    $term_array_ids = array_map('intval', $term_array_ids);
                    $term_id_to_search = array_pop($term_array_ids); // only allow for a single term to be used. picked pseudo randomly
                } else {
                    $term_id_to_search = false;
                }

                $term_id_to_search = apply_filters('_th90_limit_adjacent_post_term_id', $term_id_to_search, $term_array_ids, $excluded_terms, $taxonomy, $previous);

                if (! empty($term_id_to_search) ) {  // allow filters to short circuit by returning a empty like value
                    $join = " INNER JOIN $wpdb->term_relationships AS tr ON p.ID = tr.object_id INNER JOIN $wpdb->term_taxonomy tt ON tr.term_taxonomy_id = tt.term_taxonomy_id"; // Only join if we are sure there is a term
                    $where = $wpdb->prepare('AND tt.taxonomy = %s AND tt.term_id IN (%d)  ', $taxonomy, $term_id_to_search); //
                }
            }
        }
    }

    $op = $previous ? '<' : '>';
    $order = $previous ? 'DESC' : 'ASC';
    $limit = 1;
    // We need 5 posts so we can filter the excluded term later on
    if (! empty($excluded_term) ) {
        $limit = 5;
    }
    $sort  = "ORDER BY p.post_date $order LIMIT $limit";
    $where = $wpdb->prepare("WHERE p.post_date $op %s AND p.post_type = %s AND p.post_status = 'publish' $where", $current_post_date, $post->post_type);
    $query = "SELECT p.ID FROM $wpdb->posts AS p $join $where $sort";

    $found_post = ''; // blank instead of false so not found is cached.
    $query_key = '_th90_adjacent_post_' . md5($query);
    $cached_result = wp_cache_get($query_key);

    if ('not found' === $cached_result ) {
        return false;
    } elseif (false !== $cached_result ) {
        return get_post($cached_result);
    }

    if (empty($excluded_term) ) {
        $result = $wpdb->get_var($query);
    } else {
        $result = $wpdb->get_results($query);
    }

    // Find the first post which doesn't have an excluded term
    if (! empty($excluded_term) ) {
        foreach ( $result as $result_post ) {
            $post_terms = get_the_terms($result_post, $taxonomy);
            $terms_array = wp_list_pluck($post_terms, 'term_id');
            if (! in_array($excluded_term, $terms_array, true) ) {
                $found_post = $result_post->ID;
                break;
            }
        }
    } else {
        $found_post = $result;
    }

    // If the post isn't found lets cache a value we'll check against. Add some variation in the caching so if a site is being crawled all the caches don't get created all the time.
    if (empty($found_post) ) {
        wp_cache_set($query_key, 'not found', 'default', 15 * MINUTE_IN_SECONDS + rand(0, 15 * MINUTE_IN_SECONDS));
        return false;
    }

    wp_cache_set($query_key, $found_post, 'default', 6 * HOUR_IN_SECONDS + rand(0, 2 * HOUR_IN_SECONDS));
    $found_post = get_post($found_post);

    return $found_post;
}

function _th90_attachment_url_to_postid( $url )
{

    $id = wp_cache_get('_th90_attachment_url_post_id_' . md5($url));
    if (false === $id ) {
        $id = attachment_url_to_postid($url);
        if (empty($id) ) {
            wp_cache_set('_th90_attachment_url_post_id_' . md5($url), 'not_found', 'default', 12 * HOUR_IN_SECONDS + mt_rand(0, 4 * HOUR_IN_SECONDS));
        } else {
            wp_cache_set('_th90_attachment_url_post_id_' . md5($url), $id, 'default', 24 * HOUR_IN_SECONDS + mt_rand(0, 12 * HOUR_IN_SECONDS));
        }
    } elseif ('not_found' === $id ) {
        return false;
    }
    return $id;
}

/**
 * Use this function to cache the comment counting in the wp menu that can be slow on sites with lots of comments
 * use like this:
 *
 * @param $post_id
 *
 * @see    wp_count_comments()
 * @return bool|false|mixed|string
 */
function _th90_cache_full_comment_counts( $counts = false, $post_id = 0 )
{
    // We are only caching the global comment counts for now since those are often in the millions while the per page one is usually more reasonable.
    if (0 !== $post_id ) {
        return $counts;
    }
    $cache_key = "vip-comments-{$post_id}";
    $stats_object = wp_cache_get($cache_key);

    // retrieve comments in the same way wp_count_comments() does
    if (false === $stats_object ) {
        $stats = get_comment_count($post_id);
        $stats['moderated'] = $stats['awaiting_moderation'];
        unset($stats['awaiting_moderation']);
        $stats_object = (object) $stats;

        wp_cache_set($cache_key, $stats_object, 'default', 30 * MINUTE_IN_SECONDS);
    }

    return $stats_object;

}

function _th90_enable_cache_full_comment_counts()
{
    add_filter('wp_count_comments', '_th90_cache_full_comment_counts', 10, 2);
}


function _th90_enable_old_slug_redirect_caching()
{
    add_action('template_redirect', '_th90_wp_old_slug_redirect', 8);
    // Hook the following actions to after the core's wp_check_for_changed_slugs - it's being hooke at prio 12
    add_action('post_updated', '_th90_flush_wp_old_slug_redirect_cache', 13, 3);
    add_action('attachment_updated', '_th90_flush_wp_old_slug_redirect_cache', 13, 3);
}

/**
 * This works by first looking in the cache to see if there is a value saved based on the name query var.
 * If one is found, redirect immediately. If nothing is found, including that there is no already cache "not_found" value we then add a hook to old_slug_redirect_url so that when the 'rea' wp_old_slug_redirect is run it will store the value in the cache @see _th90_set_old_slug_redirect_cache(). If we found a not_found we remove the template_redirect so the slow query is not run.
 */
function _th90_wp_old_slug_redirect()
{
    global $wp_query;
    if (is_404() && '' !== $wp_query->query_vars['name'] ) {

        $redirect = wp_cache_get('old_slug' . $wp_query->query_vars['name']);

        if (false === $redirect ) {
            // Run the caching callback as the very firts one in order to capture the value returned by WordPress from database. This allows devs from using `old_slug_redirect_url` filter w/o polluting the cache
            add_filter('old_slug_redirect_url', '_th90_set_old_slug_redirect_cache', -9999, 1);
            // If an old slug is not found the function returns early and does not apply the old_slug_redirect_url filter. so we will set the cache for not found and if it is found it will be overwritten later in _th90_set_old_slug_redirect_cache()
            wp_cache_set('old_slug' . $wp_query->query_vars['name'], 'not_found', 'default', 12 * HOUR_IN_SECONDS + mt_rand(0, 12 * HOUR_IN_SECONDS));
        } elseif ('not_found' === $redirect ) {
            // _th90_set_old_slug_redirect_cache() will cache 'not_found' when a url is not found so we don't keep hammering the database
            remove_action('template_redirect', 'wp_old_slug_redirect');
            return;
        } else {
            /**
 * This filter is documented in wp-includes/query.php.
*/
            $redirect = apply_filters('old_slug_redirect_url', $redirect);
            wp_redirect($redirect, 301); // this is kept to not safe_redirect to match the functionality of wp_old_slug_redirect
            exit;
        }
    }
}
function _th90_set_old_slug_redirect_cache( $link )
{
    global $wp_query;
    if (! empty($link) ) {
        wp_cache_set('old_slug' . $wp_query->query_vars['name'], $link, 'default', 7 * DAY_IN_SECONDS);
    }
    return $link;
}
function _th90_flush_wp_old_slug_redirect_cache( $post_id, $post, $post_before )
{
    // Don't bother if slug hasn't changed.
    if ($post->post_name == $post_before->post_name ) {
        return;
    }

    // We're only concerned with published, non-hierarchical objects.
    if (! ( 'publish' === $post->post_status || ( 'attachment' === get_post_type($post) && 'inherit' === $post->post_status ) ) || is_post_type_hierarchical($post->post_type) ) {
        return;
    }

    // Flush cache for all old slugs.
    $old_slugs = (array) get_post_meta($post_id, '_wp_old_slug');

    foreach ( $old_slugs as $old_slug ) {
        wp_cache_delete('old_slug' . $old_slug, 'default');
    }

    // FLush cache for new post_name since it could had been among old slugs before this update.
    wp_cache_delete('old_slug' . $post->post_name, 'default');
}

/**
* Enables object caching for the response sent by Instagram when querying for Instagram image HTML.
*
* This cannot be included inside Jetpack because it ships with caching disabled by default.
* By enabling caching it's possible to save time in uncached page renders.
**/
add_filter('instagram_cache_oembed_api_response_body', '__return_true');