Login   Register  
PHP Classes
elePHPant
Icontem

File: engine/handler.sitemap.php

Recommend this page to a friend!
Stumble It! Stumble It! Bookmark in del.icio.us Bookmark in del.icio.us
  Classes of Kristo Vaher  >  Wave Framework  >  engine/handler.sitemap.php  >  Download  
File: engine/handler.sitemap.php
Role: Application script
Content type: text/plain
Description: Sitemap Handler
Class: Wave Framework
MVC framework for building Web sites and APIs
Author: By
Last change: It is now possible to return picture files and resource files as BASE64 encoded if you provide 'base64' parameter as a dynamic URL parameter. Added 'url-absolute' and 'url-relative' to the already existing 'request-url' variables that the default URL Controller returns to the View. Added 'output' return type that simply returns the whatever is stored in response arrays 'www-data' key. When using getState() method on a variable that does not exist, then it generates a notice in debugger log. Added an option to restrict URL's based on user agent being matched, this allows to create mobile specific redirects and other user agent specific features. Some State variable names have been changed to clean up the State namespace, this can break backwards compatibility. Chech the full list at update documentation. Updated jQuery to 1.9.0 release. Added isDeveloper() call and developer-ip and developer-user-agent configuration settings. Fixed a bug with Javascript API Wrapper parallel form requests.
Date: 2013-01-30 05:38
Size: 10,205 bytes
 

Contents

Class file image Download
<?php
/**
 * Wave Framework <http://www.waveframework.com>
 * Sitemap Handler
 *
 * Sitemap Handler is used to return sitemap.xml files, if a request is made to such a file. This 
 * handler either returns the existing /sitemap.xml file, or generates a new one based on sitemap 
 * files in /resources/ folder and the languages defined in configuration.
 *
 * @package    Index Gateway
 * @author     Kristo Vaher <kristo@waher.net>
 * @copyright  Copyright (c) 2012, Kristo Vaher
 * @license    GNU Lesser General Public License Version 3
 * @tutorial   /doc/pages/handler_sitemap.htm
 * @since      1.5.0
 * @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();
    }
    
// Sitemap is always returned in XML format
    
header('Content-Type: text/xml;charset=utf-8;'); 
    
    
// This flag stores whether cache was used
    
$cacheUsed=false;
    
// Default cache timeout of one month, unless timeout is set
    
if(!isset($config['sitemap-cache-timeout'])){
        
$config['sitemap-cache-timeout']=14400// Four hours
    
}
// GENERATING SITEMAP
    // Sitemap is generated only if it does not exist in root
    
if(!file_exists(__ROOT__.'sitemap.xml')){
    
        
// ASSIGNING PARAMETERS FROM REQUEST
            // If filename includes & symbol, then system assumes it should be dynamically generated
            
$parameters=array_unique(explode('&',$resourceFile));
            
// Looking for cache
            
$cacheFilename=md5('sitemap.xml'.$config['version'].$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 SITEMAP OR LOADING FROM CACHE
            // If sitemap cannot be found from cache, it is generated
            
if(in_array('nocache',$parameters) || ($lastModified==$_SERVER['REQUEST_TIME'] || $lastModified<($_SERVER['REQUEST_TIME']-$config['sitemap-cache-timeout']))){
            
                
// 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 sitemap.txt 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 SITEMAP STRING 
                    // Sitemap XML string is stored here
                    
$siteMapXML='';
                    
// Sitemap can only be generated if system actually uses languages and sitemap files
                    
if(!empty($state->data['languages'])){
                        
// XML header
                        
$siteMapXML.='<?xml version="1.0" encoding="utf-8"?>';
                        
                        
// Defining sitemap schema
                        
$siteMapXML.='<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">';
                        
                        
// Root depends on whether website is forced to work on HTTPS or not
                        
$root=((isset($config['limiter-https']) && $config['limiter-https']==true)?'https://':'http://').$_SERVER['HTTP_HOST'].$state->data['url-web'];
                        
                        
// Every language defined in state is generated for sitemap
                        
foreach($state->data['languages'] as $language){
                        
                            
// Checking for existence of URL Map file
                            
if(file_exists(__ROOT__.'overrides'.DIRECTORY_SEPARATOR.'resources'.DIRECTORY_SEPARATOR.$language.'.sitemap.ini')){
                                
// Overrides can be used if they are stored in /overrides/resources/ subfolder
                                
$siteMap=parse_ini_file(__ROOT__.'overrides'.DIRECTORY_SEPARATOR.'resources'.DIRECTORY_SEPARATOR.$language.'.sitemap.ini',true,INI_SCANNER_RAW);
                            } elseif(
file_exists(__ROOT__.'resources'.DIRECTORY_SEPARATOR.$language.'.sitemap.ini')){
                                
// If there was no override, the URL Map is loaded from /resources/
                                
$siteMap=parse_ini_file(__ROOT__.'resources'.DIRECTORY_SEPARATOR.$language.'.sitemap.ini',true,INI_SCANNER_RAW);
                            }
                            
                            
// If first language does not require language node in URL's then it is ignored
                            
if($language==$state->data['language'] && $state->data['enforce-first-language-url']==false){
                                
$langRoot=$root;
                            } else {
                                
$langRoot=$root.$language.'/';
                            }
                            
                            
// As long as sitemap file is not empty, the nodes are added to output
                            
if(!empty($siteMap)){
                            
                                
// Read more about $node values from Sitemap files
                                
foreach($siteMap as $url=>$node){
                                
                                    
// Hidden URL's and URL's with redirects are not placed in sitemap
                                    
if((!isset($node['permissions']) || $node['permissions']=='*' || $node['permissions']=='') && (!isset($node['hidden']) || $node['hidden']!=true) && !isset($node['temporary-redirect']) && !isset($node['permanent-redirect'])){
                                    
                                        
// Building single URL node
                                        
$siteMapXML.='<url>';
                                            
// Location is the full URL of the page
                                            
if(strpos($url,':')!==false){
                                                
$url=explode(':',$url);
                                                
$siteMapXML.='<loc>'.$langRoot.$url[0].'</loc>';
                                            } else {
                                                
$siteMapXML.='<loc>'.$langRoot.$url.'/</loc>';
                                            }
                                            
// Priority is a value from 0.0 to 1.0 (default is 0.5). This tells how important this URL is in relation to other URL's
                                            
if(isset($node['priority'])){
                                                
$siteMapXML.='<priority>'.$node['priority'].'</priority>';
                                            }
                                            
// This can be 'always','hourly','daily','weekly','monthly','yearly','never' and tell robots how often this URL changes
                                            
if(isset($node['change-frequency'])){
                                                
$siteMapXML.='<changefreq>'.$node['change-frequency'].'</changefreq>';
                                            }
                                            
// It is possible to state in Sitemap when the URL was last modified
                                            
if(isset($node['last-modified'])){
                                                
// This should be in YYYY-MM-DD format
                                                
$siteMapXML.='<lastmod>'.$node['last-modified'].'</lastmod>';
                                            }
                                        
$siteMapXML.='</url>';
                                    }
                                    
                                }
                                
                            }
                        }
                        
                        
// Closing the sitemap tag
                        
$siteMapXML.='</urlset>';
                        
                    }
                    
                
// 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,$siteMapXML)){
                        
trigger_error('Cannot create resource cache',E_USER_ERROR);
                    }
                
            } else {
                
// Notifying logger that cache was used
                
$cacheUsed=true;
            }
            
        
// HEADERS
            // If cache is used, then proper headers will be sent
            
if(in_array('nocache',$parameters)){
                
// user agent is told to cache these results for set duration
                
header('Cache-Control: no-cache,no-store');
                
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');
            } else {
                
// user agent is told to cache these results for set duration
                
header('Cache-Control: public,max-age='.$config['sitemap-cache-timeout']);
                
header('Expires: '.gmdate('D, d M Y H:i:s',($_SERVER['REQUEST_TIME']+$config['sitemap-cache-timeout'])).' 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);
            
// File is deleted if cache was requested to be off
            
if(in_array('nocache',$parameters)){
                
unlink($cacheDirectory.$cacheFilename);
            }
    } else {
    
        
// RETURNING EXISTING SITEMAP
        
            // This is technically considered as using cache
            
$cacheUsed=true;
        
            
// Cache headers
            
header('Cache-Control: public,max-age='.$config['sitemap-cache-timeout']);
            
header('Expires: '.gmdate('D, d M Y H:i:s',($_SERVER['REQUEST_TIME']+$config['sitemap-cache-timeout'])).' GMT');
            
// Last modified header
            
header('Last-Modified: '.gmdate('D, d M Y H:i:s',filemtime(__ROOT__.'sitemap.xml')).' GMT');
            
// Content length of the file
            
$contentLength=filesize(__ROOT__.'sitemap.xml');
            
// Content length is defined that can speed up website requests, letting user agent to determine file size
            
header('Content-Length: '.$contentLength);
            
// Since sitemap.xml did exist in root, it is simply returned
            
readfile(__ROOT__.'sitemap.xml');
        
    }
    
// 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'=>'sitemap','cache-used'=>$cacheUsed,'content-length-used'=>$contentLength,'database-query-count'=>((isset($databaseConnection))?$databaseConnection->queryCounter:0)));
        
// Writing log entry
        
$logger->writeLog('sitemap');
    }
?>