Building accessible, standards compliant websites and web applications for businesses and organisations.

With over 20 years experience in software development and 10 years in web technologies, including (X)HTML, CSS, JavaScript, PHP and MySQL.

All websites that are developed follow the standards as set out by the World Wide Web Consortium (W3C) to ensure current and future compatibility with browsers and devices.

Web pages are marked up semantically to be search engine friendly (SEO) to help search engines index your site content as required.

Available for complete site builds, server/client script development and consulting services.

<?php
/**
 * XML Sitemap Generator
 *    - Generates XML for body <url>...</url> sections of XML sitemap
 *    - Other modules that handle pages and URLs should register callback functions that return the appropriate data (assoc array)
 *
 * @link http://en.wikipedia.org/wiki/Sitemap_index#Submitting_Sitemaps
 *
 * @author Andrew Pendlebury <andy -at- w3development -dot- co -dot- uk>
 * @category Pages
 * @version 1.00.0000 2011-11-24 11:30
 * @package W3dSuperLite
 */
 
/**
 * Dependencies
 *    - W3dPluginAbstract
 *    - W3dRegistry
 */
 
/**
 * XML Sitemap
 */
class W3dSitemapXml extends W3dPluginAbstract {

    
/**
     * Array of methods to call in order to retrieve page data from external modules
     *    - This class does not know about all the other modules (there could be many) that handle pages
     *        But all other modules know about this one.
     */
    
protected $_callbacks = array();
    
    
/**
     * Page/URL data
     *    - The URL (<loc>) is the key
     */
    
protected $_pages = array();
    
    
/**
     * Constructor
     * @param object $registry    Instance of registry object
     */
    
public function __construct($registry) {
        
parent::__construct($registry);
        
        
/**
         * Plugin properties
         */
        
$this->_pluginId 'sitemapXml';
        
$this->_pluginVersion 1.0;
        
$this->_pluginDate strtotime('2013-11-24 11:30 UTC');
        
$this->_pluginName 'XML Sitemap Generation';
        
$this->_pluginDescription 'Other plugins (including the core page handler) register callbacks in this plugin in order to generate an XML sitemap. If other plugins generate pages that aren\'t defined as part of the "pages" plugin then they can be accounted for here by registering an appropriate callback. Note that there is also a page handler file associated with this plugin.';
        
//$this->_pluginOrder = -1000;
    
}
    
    
/**
     * Register a callback function
     *    - The callback function must return an assoc array with the following fields:
     *        'LOC' (mandatory) - Root relative URL
     *        'LASTMOD' (optional) - Unix timestamp
     *        'CHANGEFREQ' (optional) - 'always', 'hourly', 'daily', 'weekly', 'monthly', 'yearly', 'never'
     *        'PRIORITY' (optional) - 0.0 to 1.0 (default 0.5)
     * @param string|array $callback    A valid callback function
     * @return void
     */
    
public function regCallback($callback) {
        
// Check if is_callable() ...?
        
$this->_callbacks[] = array (
            
'CALLBACK' => $callback,
            
'PROCESSED' => false,
        );
    }
    
    
/**
     * Get/generate the XML Sitemap.
     *    - Note that this method does not generate the XML Declaration and <urlset> root element
     */
    
public function getSitemapXml() {
        
$xml '';
    
        
// For constructing absolute URLs
        
$ssl = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off');
        
$baseUrl $ssl 'https' 'http';
        
$baseUrl .= '://'.$_SERVER['HTTP_HOST'];
    
        
// Process callbacks
        
foreach ($this->_callbacks as &$callback) {
            if (
$callback['PROCESSED']) {
                continue;
            }
            
// Check if callable...?
            
$pages call_user_func($callback['CALLBACK']);
            
// Assign to internal _pages array
            
foreach ($pages as $page) {
                
$lastMod null;
                if (isset(
$page['LASTMOD'])) {
                    
// eg. 2005-08-15T15:52:01+00:00
                    
$lastMod date(DATE_W3C,$page['LASTMOD']);
                }
                
$changeFreq = isset($page['CHANGEFREQ']) ? $page['CHANGEFREQ'] : null;
                
$priority = isset($page['PRIORITY']) ? $page['PRIORITY'] : null;

                
$this->_pages[$page['LOC']] = array (
                    
'LOC' => $baseUrl.$page['LOC'],    // Mandatory
                    
'LASTMOD' => $lastMod,
                    
'CHANGEFREQ' => $changeFreq,
                    
'PRIORITY' => $priority,
                );
            }
            
$callback['PROCESSED'] = true;
        }
        unset(
$callback);
        
        
// Construct XML
        
$tab "\t";
        
$nl PHP_EOL;
        foreach (
$this->_pages as $record) {
            
$xml .= $tab.'<url>'.$nl;
            foreach (
$record as $field => $value) {
                if (isset(
$value)) {
                    
$tag strtolower($field);
                    
$xml .= $tab.$tab.'<'.$tag.'>'.$record[$field].'</'.$tag.'>'.$nl;
                }
            }
            
$xml .= $tab.'</url>'.$nl;
        }
        
        return 
$xml;
    }

}
// W3dSitemapXml