Yii 1.1: Create sitemap.xml file dynamically on root folder with one hit

10 followers

I had created one controller file which can create sitemap.xml file(which is used for seo, google crawler and many other puropse) dynamically with one run.

This article is use for Yii framework basic structure and This FrontEnd/BackEnd seperated directory structure

I had reference This Extension for development.

Create one controller file in controller folder named KsitemapController and copy paste below code in that controller file and Just run that controller with its default action ( index action )

You just need to change default variable as your requirements,

$protectedControllers => "Contain array of controllers which should not include in sitemap.xml file, means its methods also not included in sitemap.xml"

$protectedActions => "Contain array of actions which should not include in sitemap.xml"

$priority, $changefreq, $lastmod are other parameters which you can set as requirement.

<?php
class KsitemapController extends Controller
{
    public $protectedControllers = array('ksitemap');   //controller array will not added in sitemap.xml
    public $protectedActions =array('site/error','site/logout');      //controller/action array will not added in sitemap.xml
    public $priority = '0.5';                           //default priority for all url
    public $changefreq = 'daily';                       //default frequency for all url
    public $lastmod = '1985-10-07';                     //default last modified date
 
    public function actionIndex()
    {
        Yii::import('application.controllers.*');
        //Yii::import('application.controllers.back.*'); //if you are using front/back type of directory structure, just define controller folder back/front
        $urls = array();
        $directory = Yii::getPathOfAlias('application.controllers');
        //$directory = Yii::getPathOfAlias('application.controllers.back'); //if you are using front/back type of directory structure, just define controller folder back/front
        $iterator = new DirectoryIterator($directory);
 
        foreach ($iterator as $fileinfo)
        {
            if ($fileinfo->isFile() and $fileinfo->getExtension() == 'php')
            {
                $className = substr($fileinfo->getFilename(), 0, -4); //strip extension
                $class = new ReflectionClass($className);
 
                foreach ($class->getMethods(ReflectionMethod::IS_PUBLIC) as $method)
                {                                       
                    $methodName = $method->getName();
                    if (strpos($methodName, 'action') === 0) //only methods starts with action included
                    {   
                        $controller = lcfirst(substr($className, 0, strrpos($className, 'Controller')));
                        $action = lcfirst(substr($methodName, 6));
                        if (!$this->isProtected($controller, $action)) //refer isProtected function
                            $this->addUrl($urls, "$controller/$action"); //refer addUrl function
                    }
                }
            }
        }
 
        //below array $url converted into required(sitemap.xml) structure       
        $xmldata = '<?xml version="1.0" encoding="utf-8"?>'; 
        $xmldata .= '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
        foreach ($urls as $url => $data)
        {
            $xmldata .= '<url>';
            $xmldata .= '<loc>'.$url.'</loc>';
            $xmldata .= '<lastmod>'.$data['lastmod'].'</lastmod>';
            $xmldata .= '<changefreq>'.$data['changefreq'].'</changefreq>';
            $xmldata .= '<priority>'.$data['priority'].'</priority>';
            $xmldata .= '</url>';
        }   
        $xmldata .= '</urlset>'; 
 
        if(file_put_contents('sitemap.xml',$xmldata))
        {
            echo "sitemap.xml file created on project root folder..";   
        }
 
    }
 
    protected function addUrl(&$urls, $action, $args = array()) //generate url and globaly default passed parameters as array
    {
        $url = Yii::app()->createAbsoluteUrl($action, $args);
 
        $prefs = array();       
        $defPrefs = array(
            'lastmod' => $this->lastmod ? $this->lastmod : date('Y-m-d'),
            'changefreq' => $this->changefreq ? $this->changefreq : 'daily',
            'priority' => $this->priority ? $this->priority : 0.5,
        );      
        $prefs = array_merge($defPrefs, $prefs);        
        $urls[$url] = $prefs;
    }
 
    protected function isProtected($controller, $action) //check protected controller/action present in publicly defined global array 
    {
        return in_array($controller, $this->protectedControllers) or 
            in_array("$controller/$action", $this->protectedActions);
    }
}

Tadaa... This is it. you can see sitemap.xml file created on project root folder.

You can directly download the zip file of controller KsitemapController.php by Click here

Total 1 comment

#10734 report it
redguy at 2012/11/20 05:27am
this is simple list of controllers and actions

..and often actions need some parameters that change the content they provide - best example is 'page' action in 'SiteController' generated with yiic which provides page content based on provided page name. Without this parameter action will throw error instead of serving anything.

Also - this solution ignores actions provided with 'actions()' method (like mentioned before 'page' action) which is standard way to use components on controllers level...

Leave a comment

Please to leave your comment.

Write new article
  • Written by: kiran sharma
  • Category: How-tos
  • Yii Version: 1.1
  • Votes: +5 / -5
  • Viewed: 10,761 times
  • Created on: Nov 19, 2012
  • Last updated: Nov 19, 2012
  • Tags: SEO, SiteMap, XML