Location: PHPKode > scripts > Zoocache > marcelklehr-zoocache/class/engine.class.php
<?php
/**
 *  Zoocache - Intelligent, neatly integrating, easily extenable output caching tool
 *  Copyright (C) 2011  Marcel Klehr <hide@address.com>
 *
 *  This program is free software; you can redistribute it and/or modify it under the 
 *  terms of the GNU General Public License as published by the Free Software Foundation;
 *  either version 3 of the License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 *  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *  See the GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along with this program;
 *  if not, see <http://www.gnu.org/licenses/>.
 *
 * @package Zoocache
 * @author Marcel Klehr <hide@address.com>
 * @copyright (c) 2011, Marcel Klehr
 */
namespace Zoo;

class Engine
{
	public $data;
	public $size;
	public $crc;
	
	/**
	 * Takes some edits to the options
	 */
	public function __construct()
	{
		header('X-Cache: Zoocache/'.ZOOCACHE_VER);
        Cache::log('Plugins: '.json_encode(Config::get('plugins')));
		
		$this->cache = Cache::init();
		
		// Force caching off when POST occured
		if (count($_POST) > 0)
			Config::set('caching', FALSE);
		
		// Force caching off when blacklist matches
		$location = $this->cache->url;
		$list = Config::get('blacklist');
		foreach($list as $entry)
		{
			if(FALSE == preg_match($entry, $location)) // FALSE: Error; 0: no matches;
				continue;
			
			Cache::log($location.' Matched blacklist entry: "'.$entry.'" Don\'t cache');
			Config::set('caching', FALSE);
			break;
		}
	}
	
	/**
	 * Initializes the caching process, loads the driver and coordinates everything
	 */
	static function init()
	{
		// Construct engine
		$engine = new Engine();
        
        // gzip compression?
        if(Config::get('gzip') === TRUE)
            ob_start('ob_gzhandler');
		
		// caching on?
		if(!Config::get('caching'))
            return;
        
        if(($c = $engine->cache->get()) !== FALSE)
        {
          /* Found Cache */
            $engine->data = $c['data'];
            $engine->size = $c['size'];
            $engine->crc = $c['crc'];
            
            // valid?
            if(time() < $c['timestamp'] + Config::get('expire'))
            {
                // flush
                print $engine->flush();
                exit;
            }
        }
        Cache::log('Cache invalid');
		
		// start output buffer and define callback
		ob_start(array($engine, 'recache'));
		ob_implicit_flush(0);
	}
	
    /**
     * Process the buffered data
     */
	function recache($chunk)
    {
        // Apply filters
        $chunk = Cache::filter($chunk);
        
		// Store cache
		if(!connection_aborted() && Config::get('caching'))
		{
			$this->cache->store($chunk);
		}
		
		$this->size = strlen($chunk);
		$this->crc = crc32($chunk);
		$this->data = $chunk;
		return $this->flush();
	}
	
	/**
	 * Handles Gzip and ETag to return the data with the right encoding
	 */
	function flush()
	{
		Cache::log('Flushing');
		
		// Build ETag
		$my_ETag = '"z' . $this->crc .'-'. $this->size . '"';
		header('ETag: '.$my_ETag);
		
		$received_ETag = isset($_SERVER['HTTP_IF_NONE_MATCH']) ? stripslashes($_SERVER['HTTP_IF_NONE_MATCH']) : '';
		
		// Check if anything is modified
		if(strpos($received_ETag, $my_ETag) !== FALSE)
		{
		  /* Nothing modified - do nothing */
			if(stripos($_SERVER['SERVER_SOFTWARE'], 'microsoft') !== FALSE)
			{
				// IIS has already sent HTTP 200
				header('Status: 304 Not Modified');
			}else{
				header('HTTP/1.0 304');
			}
			return '';
			
		}else{
            // Something modified - return cached data
			return $this->data;
		}
	}
}
?>
Return current item: Zoocache