<?php 
/** 
 * Wave Framework <http://github.com/kristovaher/Wave-Framework> 
 * Appcache Handler 
 * 
 * Appcache Handler is used to return an appcache manifest to the browser for pages that use  
 * Appcache. If this appcache file already exists in project root folder, then it is returned 
 * directly from that source. Otherwise the file will be generated. 
 * 
 * @package    Index Gateway 
 * @author     Kristo Vaher <[email protected]> 
 * @copyright  Copyright (c) 2012, Kristo Vaher 
 * @license    GNU Lesser General Public License Version 3 
 * @tutorial   /doc/pages/handler_appcache.htm 
 * @since      3.4.1 
 * @version    3.5.0 
 */ 
// INITIALIZATION 
    // Stopping all requests that did not come from Index Gateway 
    if(!isset($resourceAddress)){ 
        header('HTTP/1.1 403 Forbidden'); 
        die(); 
    } 
    // Appcache manifest file requires this header 
    header('Content-Type: text/cache-manifest;'); 
     
    // This flag stores whether cache was used 
    $cacheUsed=false; 
// GENERATING APPCACHE MANIFEST FILE 
    // Manifest file is generated only if it does not exist in root 
    if(!file_exists(__ROOT__.$resourceFile)){ 
     
        // Finding data about the request 
            // Looking for cache 
            $cacheFilename=md5($resourceFile.'&'.$config['version-system'].'&'.$config['version-api'].'&'.$resourceRequest).'.tmp'; 
            $cacheDirectory=__ROOT__.'filesystem'.DIRECTORY_SEPARATOR.'cache'.DIRECTORY_SEPARATOR.'resources'.DIRECTORY_SEPARATOR.substr($cacheFilename,0,2).DIRECTORY_SEPARATOR; 
            // If cache file exists then cache modified is considered that time 
            if(file_exists($cacheDirectory.$cacheFilename)){ 
                $lastModified=filemtime($cacheDirectory.$cacheFilename); 
            } else { 
                // Otherwise it is server request time 
                $lastModified=$_SERVER['REQUEST_TIME']; 
            } 
             
        // GENERATING NEW MANIFEST FILE OR LOADING FROM CACHE 
            // If a new manifest file is requested 
            if($lastModified==$_SERVER['REQUEST_TIME']){ 
             
                // STATE AND DATABASE 
                 
                    // State stores a lot of settings that are taken into account during Sitemap generation 
                    require(__ROOT__.'engine'.DIRECTORY_SEPARATOR.'class.www-state.php'); 
                    $state=new WWW_State($config); 
                    // Connecting to database, if configuration is set 
                    // Uncomment this if you actually need to use database connection for manifest file 
                    // if(isset($config['database-name']) && $config['database-name']!='' && isset($config['database-type']) && isset($config['database-host']) && isset($config['database-username']) && isset($config['database-password'])){ 
                        // require(__ROOT__.'engine'.DIRECTORY_SEPARATOR.'class.www-database.php'); 
                        // $databaseConnection=new WWW_Database($config['database-type'],$config['database-host'],$config['database-name'],$config['database-username'],$config['database-password'],((isset($config['database-errors']))?$config['database-errors']:false),((isset($config['database-persistent']))?$config['database-persistent']:false)); 
                    // } 
                     
                // GENERATING APPCACHE MANIFEST 
                 
                    // This finds the web root, if set 
                    if(!$config['url-web']){ 
                        $config['url-web']=str_replace('index.php','',$_SERVER['SCRIPT_NAME']); 
                    } 
                     
                    $appcache='CACHE MANIFEST'."\n"; 
                    $appcache.='# System version '.$config['version-system']."\n"; 
                    $appcache.='NETWORK:'."\n"; 
                    $appcache.='*'."\n"; 
                    $appcache.='CACHE:'."\n"; 
                    $appcache.=$config['url-web'].'resources/styles/reset.css&style.css'."\n"; 
                    $appcache.='FALLBACK:'."\n"; 
                    $appcache.='/ '.$config['url-web'].'resources/offline.htm'."\n"; 
                     
                // WRITING TO CACHE 
             
                    // Resource cache is cached in subdirectories, if directory does not exist then it is created 
                    if(!is_dir($cacheDirectory)){ 
                        if(!mkdir($cacheDirectory,0755)){ 
                            trigger_error('Cannot create cache folder',E_USER_ERROR); 
                        } 
                    } 
                    // Data is written to cache file 
                    if(!file_put_contents($cacheDirectory.$cacheFilename,$appcache)){ 
                        trigger_error('Cannot create resource cache',E_USER_ERROR); 
                    } 
             
            } else { 
                // Setting the flag for logger 
                $cacheUsed=true; 
            } 
             
        // HEADERS 
         
            // Appcache is technically never cached 
            header('Cache-Control: public,max-age=0'); 
            header('Expires: '.gmdate('D, d M Y H:i:s',$_SERVER['REQUEST_TIME']).' GMT'); 
            header('Last-Modified: '.gmdate('D, d M Y H:i:s',$lastModified).' GMT'); 
             
            // Content length of the file 
            $contentLength=filesize($cacheDirectory.$cacheFilename); 
            // Content length is defined that can speed up website requests, letting user agent to determine file size 
            header('Content-Length: '.$contentLength);   
             
        // OUTPUT 
            // Returning the file to user agent 
            readfile($cacheDirectory.$cacheFilename); 
         
    } else { 
         
        // RETURNING EXISTING MANIFEST FILE 
         
            // This is technically considered as using cache 
            $cacheUsed=true; 
         
            // Appcache is technically never cached 
            header('Cache-Control: public,max-age=0'); 
            header('Expires: '.gmdate('D, d M Y H:i:s',$_SERVER['REQUEST_TIME']).' GMT'); 
            // Last modified header 
            header('Last-Modified: '.gmdate('D, d M Y H:i:s',filemtime(__ROOT__.$resourceFile)).' GMT'); 
            // Content length of the file 
            $contentLength=filesize(__ROOT__.$resourceFile); 
            // Content length is defined that can speed up website requests, letting user agent to determine file size 
            header('Content-Length: '.$contentLength); 
            // Since the manifest did exist in root, it is simply returned 
            readfile(__ROOT__.$resourceFile); 
    } 
     
// WRITING TO LOG 
    // If Logger is defined then request is logged and can be used for performance review later 
    if(isset($logger)){ 
        // Assigning custom log data to logger 
        $logger->setCustomLogData(array('category'=>'appcache','cache-used'=>$cacheUsed,'content-length-used'=>$contentLength,'database-query-count'=>((isset($databaseConnection))?$databaseConnection->queryCounter:0))); 
        // Writing log entry 
        $logger->writeLog(); 
    } 
?>
 
 |