<?php
class IMI_Fragment_Cache {
	
	const GROUP = 'transient';
	
	private $key, $url, $ttl, $pgd;
	
	public function __construct( $key = false, $url = false, $pgd = false ) {
		
		$this->key = $key;
		
		$this->url = $this->md5hash( $url );
		
		$this->ttl = 604800;
		
		$this->pgd = ( $pgd ) ? '_' . $pgd : false;
	}
	
	private function md5hash($n) {
		
		if ( !$n ) return;
		
		return substr( @md5( $n ), 0, 8 );
	}
	
	public function output() {
		
		return false;
		
		$output = get_transient( $this->key . '_' . $this->url . $this->pgd, self::GROUP );
		
		if ( !empty( $output ) ) {
			
			echo $output;
			
			return true;
			
		} else {
			
			ob_start();
			
			return false;
		}
	}
	
	public function store() {
		
		return;
		
		$output = html_minify( ob_get_flush() );
		
		set_transient( $this->key . '_' . $this->url . $this->pgd, $output, self::GROUP, $this->ttl );
	}
	
	public function delete( $key = false , $url = false ) {
		
		global $wpdb;
		
		$this->key = ($key) ? $key : $this->key;
		$this->url = ($url) ? $this->md5hash( $url ) : $this->url;
		
		if ( class_exists( 'Memcached' ) ) {
			
			wp_cache_delete( $this->key . "_" . $this->url, self::GROUP );
			
		}
		
		$wpdb->query( "DELETE FROM `$wpdb->options` WHERE `option_name` LIKE ('_transient_" . $this->key . "_" . $this->url . "%')" );
		$wpdb->query( "DELETE FROM `$wpdb->options` WHERE `option_name` LIKE ('_transient_timeout_" . $this->key . "_" . $this->url . "%')" );
	}
	
	public function clear() {
		
		global $wpdb;
		
		if ( class_exists( 'Memcached' ) ) {
			
			wp_cache_flush();
		
		}
		
		$wpdb->query( "DELETE FROM `$wpdb->options` WHERE `option_name` LIKE ('_transient_%')" );
		$wpdb->query( "DELETE FROM `$wpdb->options` WHERE `option_name` LIKE ('_transient_timeout_%')" );
	}
}

// clear menu cache on update
function clear_menu_cache( $id, $data = null ) {
	
	$frag = new IMI_Fragment_Cache( 'mnt' );
	$frag->delete();
    
	$frag = new IMI_Fragment_Cache( 'mnb' );
	$frag->delete();
}
add_action( 'wp_update_nav_menu', 'clear_menu_cache', 10, 2 );

// clear theme cache on update
function clear_theme_cache( $value, $post_id, $field ) {
	
	$screen = get_current_screen();
	
	if ( $screen->base == 'settings_page_profile-settings' ) {
	
		if (@$_POST['_acfchanged']) {
			
			$frag = new IMI_Fragment_Cache();
			
			/* $frag->delete( 'sli' );
			$frag->delete( 'htb' );
			$frag->delete( 'bls' );
			$frag->delete( 'hdt' );
			$frag->delete( 'hdb' );
			$frag->delete( 'ftr' ); */
			
			$frag->clear();
		}
	}
	
	return $value;
}
add_filter( 'acf/update_value', 'clear_theme_cache', 10, 3 );

// clear widget cache on update
function clear_widget_cache( $instance, $new_instance, $old_instance, $widget ) {
	
	$frag = new IMI_Fragment_Cache( $widget->id );
	$frag->delete();
	
	return $instance;
}
add_filter( 'widget_update_callback', 'clear_widget_cache', 10, 4 );

// clear post cache on update
function clear_post_cache( $post_ID, $post, $update ) {
	
	if (@$update) {
		
		$url = get_permalink( $post->ID );
		
		$frag = new IMI_Fragment_Cache();
		$frag->delete( 'crb' , $url );
		$frag->delete( 'pst' , $url );
		
		if ( $post->post_type == 'post' ) {
			
			$term_list = wp_get_post_terms( $post->ID, 'category', array( "fields" => "all" ) );
			
			foreach ( $term_list as $term_single ) {
				
				$frag->delete( 'tax', get_term_link( $term_single->term_id, $term_single->taxonomy ) );
				
				$frag->delete( 'frm', get_term_link( $term_single->term_id, $term_single->taxonomy ) );
			}
		}
	}
}
add_action( 'save_post', 'clear_post_cache', 10, 3 );

// clear post terms on update
function clear_post_terms_cache( $object_id, $terms, $tt_ids, $taxonomy, $append, $old_tt_ids ) {
	
	$term_list = array_diff( $tt_ids, $old_tt_ids );
	$term_list = array_merge( $term_list, array_diff( $old_tt_ids, $tt_ids ) );
	
	if ($term_list) {
		
		$frag = new IMI_Fragment_Cache();
		
		foreach ( $term_list as $term_single ) {
			
			$frag->delete( 'tax', get_term_link( $term_single, $taxonomy ) );
			
			$frag->delete( 'frm', get_term_link( $term_single, $taxonomy ) );
		}
	}
}
add_action( 'set_object_terms', 'clear_post_terms_cache', 10, 6);

// clear term cache on update
function clear_term_cache( $term_id, $tt_id, $taxonomy ) {
	
	$url = get_term_link( $term_id, $taxonomy );
	
	$frag = new IMI_Fragment_Cache( 'tax', $url );
	$frag->delete();
	
	if ( $ancestors = get_ancestors( $term_id, $taxonomy ) ) {
		
		foreach ( $ancestors as $term_single ) {
		
			$frag->delete( 'tax', get_term_link( $term_single, $taxonomy ) );
			
			$frag->delete( 'frm', get_term_link( $term_single, $taxonomy ) );
		}
	}
	
	$query = new WP_Query(
					
		array( 
			'category__and' 	=> $term_id,
			'hide_empty' 		=> 0,
			'posts_per_page' 	=> -1,
		)
	);
	
	if ( $siblings = $query->get_posts() ) {
		
		foreach ( $siblings as $sib ) {
				
			$frag->delete( 'pst' , get_permalink( $sib->ID ) );
		}
	}
	
	wp_reset_postdata();
}
// add_action( 'edited_term', 'clear_term_cache', 10, 3 );

/* add custom button to admin bar */
function custom_fragment_button() {
	
	global $wp, $wp_admin_bar;
	
	if ($wp->request != 'sitemap') {
	
		$args = array(
			'id' => 'imi-fragment-cache',
			'title' => __( 'Clear Cache' , 'profile' ),
			'href' => admin_url('admin.php?action=clear_fragment_cache&amp;retURL=' . home_url( $_SERVER['REQUEST_URI'] ) ),
			'meta' => array(
				'class' => 'theme-options'
			)
		);
		
		$wp_admin_bar->add_node($args);
	}
}
// add_action( 'admin_bar_menu', 'custom_fragment_button', 99 );

/* admin bar front style */
function custom_fragment_button_style() {
	
	echo '
		<style>
		#wpadminbar #wp-admin-bar-imi-fragment-cache a.ab-item, #wpadminbar #wp-admin-bar-imi-fragment-cache a.ab-item:hover {
			color:#F50000;
			font-weight:bold;
		}
			#wpadminbar #wp-admin-bar-imi-fragment-cache a.ab-item:before {
				content: "\f182";
				color:#F50000;
			}
		</style>
	';
}
add_action( 'wp_head', 'custom_fragment_button_style' );

/* clear fragment cache */
function clear_fragment_cache() {
	
	$frag = new IMI_Fragment_Cache();
	$frag->clear();
	
	$retURL = (isset($_GET['retURL'])) ? $_GET['retURL'] : false;
	
	exit( wp_redirect( $retURL ) );
}
add_action( 'admin_action_clear_fragment_cache', 'clear_fragment_cache' );
?>