Skip to content
Derek Jones edited this page Jul 5, 2012 · 7 revisions

Introduction

I have whipped up a very simple and easy-to-use library for automatically building sitemaps for your CodeIgniter web application.

Features

  • NEW: generate() method to build a complete site map
  • NEW: easy filtering in case you want to exclude certain controllers or method names (see the sample controller below)
  • Supports templates
  • Can be used to just show pages in one specific controller via the get_links() method

Requirements

  • CodeIgniter (Built on version 1.53, should work with later versions fine)
  • Extended Parser class -- I created an extension of the parser class, which simply adds a method called sparse() which will allow you to parse a template stored as a string variable instead of a file. You can get the extended library below.
  • PHP5. This library uses PHP5's Reflection class to analyze CodeIgniter controllers.

Sample controller

<?php

class Sitemap extends Controller {

    function Sitemap()
    {
        parent::Controller();
            $this->load->library('sitemap'); 
    }
    
    function index()
    {
        // Show the index page of each controller (default is FALSE)
        $this->sitemap->set_option('show_index', true);

        // Exclude all methods from the "Test" controller
        $this->sitemap->ignore('Test', '*');

        // Exclude all methods from the "Job" controller
        $this->sitemap->ignore('Job', '*');

        // Exclude a list of methods from any controller
        $this->sitemap->ignore('*', array('view', 'create', 'edit', 'delete'));

        // Exclude this controller
        $this->sitemap->ignore('Sitemap', '*'); 

        // Show the sitemap
        echo '<h1>Sitemap</h1>';
        echo $this->sitemap->generate();
    }
}

?>

Setup

Just copy and paste both of the libraries below into your application/libraries folder:

Sitemap.php

<?php  if (!defined('BASEPATH')) exit('No direct script access allowed');

/**
 * A very simple sitemap link generator
 *
 * This class uses the PHP5 Reflection class to find all the public methods
 * in a CodeIgniter controller class and generate a list of links.
 *
 * @author         Jonathon Hill <[email protected]>
 * @license        CodeIgniter license
 * @requires    MY_Parser extended Parser class [added sparse() for parsing templates stored in a string var]
 * @requires    CodeIgniter 1.6 and PHP5
 * @version        1.1
 *
 */
class Sitemap {


    /**
     * CodeIgniter base object reference
     *
     * @var object
     */
    private $CI;


    /**
     * Sitemap links template
     *
     * @var string
     */
    private $template = '<h2><a href="{section_index}">{section_text}</a></h2><ul>{links}<li><a href="{link_url}">{link_text}</a></li>{/links}</ul>';
    private $template_file; // optional sitemap template file


    /**
     * Hide the index page by default
     *
     * @var boolean
     */
    private $show_index = false;


    /**
     * Method names to ignore
     *
     * @var array
     */
    private $ignore = array(
        '*' => array(
            'get_instance',
            'controller',
            'ci_base'
        )
    );


    /**
     * Sitemap object initialization
     *
     */
    function __construct() {
        $this->CI =& get_instance();
        $this->CI->load->library('parser');
    }


    /**
     * Set configuration option(s).
     *
     * Usage:
     *     $this->sitemap->set_option($option, $value);
     *     $this->sitemap->set_option(array(
     *         'option' => 'value',
     *         ...
     *     ));
     *
     * Options:
     *     template           (string) template stored in string
     *     template_file   &#40;string&#41; template stored in file
     *     show_index      (bool) show or hide the index page
     *
     * @param mixed  $option
     * @param mixed  $value
     * @return boolean
     */
    function set_option($option, $value)
    {
        if(is_array($option))
        {
            foreach($option as $opt => $val)
            {
                if($opt == 'ignore') continue;
                if(isset($this->$opt)) $this->$opt = $val;
            }
            return true;
        }
        elseif(isset($this->$option) && $option != 'ignore')
        {
            $this->$option = $value;
            return true;
        }
        else
        {
            return false;
        }
    }


    /**
     * Return a configuration option
     *
     * @param string $option
     * @return mixed
     */
    function get_option($option)
    {
        return ($this->$option)? $this->option : false;
    }


    /**
     * Ignore a controller or specific pages in a controller
     * Usage:
     *     $this->sitemap->ignore('controller', '*');    // completely ignore a controller
     *     $this->sitemap->ignore('controller', array('page1', 'page2'));    // ignore certain pages
     *
     *
     * @param string $controller
     * @param mixed $pages
     */
    function ignore($controller, $pages)
    {
        $controller = strtolower($controller);
        if(is_array($pages)) {
            array_walk_recursive($pages, 'Sitemap::stl_callback');
        }
        else {
            $pages = strtolower($pages);
        }

        if(isset($this->ignore[$controller]) AND is_array($this->ignore[$controller])) $pages = array_merge($this->ignore[$controller], (array) $pages);
        $this->ignore[$controller] = $pages;
    }


    /**
     * Build a list of pages in a controller
     *
     * @param string $page        (optional) Build all the links for a specific controller
     * @return string
     */
    function get_links($class = null)
    {
        // Use the PHP5 Reflection class to introspect the controller
        $controller = new ReflectionClass($class);

        $data['links'] = array();
        $data['section_index'] = strtolower(site_url($class));
        $data['section_text'] = ucwords(strtr($class, array('_'=>' ')));

        foreach($controller->getMethods() as $method)
        {
            // skip methods that begin with '_'
            if(substr($method->name, 0, 1) == '_') continue;

            // skip globally ignored names
            if(in_array(strtolower($method->name), $this->ignore['*'])) continue;

            // skip ignored controller methods
            if(isset($this->ignore[strtolower($class)]) AND in_array(strtolower($method->name), (array) $this->ignore[strtolower($class)])) continue;

            // skip index page
            if($method->name == 'index' && !$this->show_index) continue;

            // skip old-style constructor
            if(strtolower($method->name) == strtolower($class)) continue;

            // skip methods that aren't public
            if(!$method->isPublic()) continue;

            // build link data for parser class
            $data['links'][] = array(
                'link_url' => strtolower(site_url("$class/$method->name")),
                'link_text'=> ucwords(strtr($method->name, array('_'=>' '))),
            );
        }

        return ($this->template_file)?
            $this->CI->parser->parse($this->template_file, $data, true) :
            $this->CI->parser->sparse($this->template, $data, true);
    }


    /**
     * Build a complete sitemap from your CI application controllers
     *
     * @return string
     */
    function generate()
    {
        $this->CI->load->helper('file');

        $sitemap = '';
        $controllers_path = APPPATH.'controllers/';
        foreach(get_filenames($controllers_path, true) as $controller) {
            list($class, $ext) = explode('.', ucfirst(basename($controller)));
            if($ext != 'php') continue;     // skip anything other than PHP files
            if(isset($this->ignore[strtolower($class)]) AND $this->ignore[strtolower($class)] == '*') continue;    // skip controllers marked as 'ignore'
            if(!class_exists($class)) include($controller);  // include the class for access
            $sitemap .= $this->get_links($class) . "\n";
        }

        return $sitemap;
    }


    /*
     * Callback wrapper function for strtolower
     * Has 2 args to prevent warnings from the strtolower() function
     */
    static function stl_callback($a, $b) { return strtolower($a); }


}

MY_Parser.php

&lt;?php  if (!defined('BASEPATH')) exit('No direct script access allowed');

// ------------------------------------------------------------------------

/**
 * Sparser Class
 *
 * @package        CodeIgniter
 * @subpackage    Libraries
 * @category    Parser
 * @author        Jonathon Hill
 * @link        [email protected]
 */
class MY_Parser extends CI_Parser {

    /**
     *  Parse a string
     *
     * Parses pseudo-variables contained in the specified string,
     * replacing them with the data in the second param
     *
     * @access    public
     * @param    string
     * @param    array
     * @param    bool
     * @return    string
     */
    function sparse($template, $data, $return = FALSE)
    {
        $CI =& get_instance();
        
        if ($template == '')
        {
            return FALSE;
        }
        
        foreach ($data as $key =&gt; $val)
        {
            if (is_array($val))
            {
                $template = $this-&gt;_parse_pair($key, $val, $template);        
            }
            else
            {
                $template = $this-&gt;_parse_single($key, (string)$val, $template);
            }
        }
        
        if ($return == FALSE)
        {
            $CI-&gt;output-&gt;final_output = $template;
        }
        
        return $template;
    }
    
}
// END Sparser Class
?&gt;
Clone this wiki locally