Skip to content

Slightly Better Caching: The Suite

Derek Jones edited this page Jul 5, 2012 · 4 revisions

Still to come...

    /**
     * Update/serve a cached file
     *
     * @access    public
     * @return    void
     */    

    function _display_cache(&$CFG, &$RTR)
    {
        // Start session
        session_start();

//  For validation messages, you want to bypass a cached form

        if ($_SERVER['REQUEST_METHOD'] != 'GET') {
            return FALSE;
        }

//  Cache URI's built with Centralzed Cache URI
//---------------------------------------------

        $cacheuri = $this->get_cache_URI();
        $uri = $cacheuri['uri'];
        $cache_path = $cacheuri['path'];
        
        $filepath = $cache_path.md5($uri);

        if ( ! @file_exists($filepath))
        {
            return FALSE;
        }
    
        if ( ! $fp = @fopen($filepath, 'rb'))
        {
            return FALSE;
        }
            
        flock($fp, LOCK_SH);
        
        $cache = '';
        if (filesize($filepath) > 0)
        {
            $cache = fread($fp, filesize($filepath));
        }

        flock($fp, LOCK_UN);
        fclose($fp);
            
//  Quickly bypass the cache so no one sees '{cached::name}' in their pages,
//  or so that a user will always bypass a 'logged out' cache.

        $token = strpos($cache,'{cached::');
        if ( FALSE !== ($data = $this->_get_from_session($CFG->item('cache_data_source'))) && is_array($data))
        {
            if ($token === FALSE)
            {
                return FALSE;
            }
        } elseif ($token !== FALSE)
        {
            return FALSE;
        }

//  Okay, so they must be returning as the same status -- back to cache...

        /*
         * Seperate headers from content.
         * This is used to output cached headers. <josh@surber.us>
         */
        list($headers, $cache) = explode("\n\n", $cache, 2);

        /*
         * Seperate each header, looking for timestamp
         * The others are output as-is. <josh@surber.us>
         */
        $headers = explode("\n", $headers);
        foreach ($headers as $header) {
            if (FALSE === strpos($header, 'X-CI-timestamp')) {
                $this->set_header($header);
            } else {
                $timestamp = substr($header, 16);
        // Has the file expired? If so we'll delete it.
                if (time() >= trim($timestamp))
                {         
                    @unlink&#40;$filepath&#41;;
                    log_message('debug', "Cache file has expired. File deleted");
                    return FALSE;
                }
            }
        }
        // --------------------------------------------------------------------

        // Display the cache
        $this->_display($cache);
        log_message('debug', "Cache file is current. Sending it to browser.");        
        log_message('debug', "Cache for ".$uri." loaded from ".$filepath);
        return TRUE;
    }
Clone this wiki locally