<?php
namespace MySite\BaseBundle\Command;

/*
 * A Symfony2 Command for generating a sitemap for your site.
 * Execute with php app/console sitemap:generate
 */

use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\DependencyInjection\SimpleXMLElement;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

class SitemapCommand extends ContainerAwareCommand
{
    const BASE_URL = 'http://www.mysite.com';
    const SAVE_LOCATION = '/var/www/mysite/sitemap.xml';
    
    private $router;
    private $links;

    private $xmlOutputFile;
    private $sitemapXml;

    protected function configure(){
        $this
            ->setName('sitemap:generate')
            ->setDescription('Generate a sitemap');
    }

    protected function init(){
        $this->router = $this->getContainer()->get('router');
        //You should also set your database connection in here if necessary.
        $this->links = array();
    }

    protected function execute(InputInterface $input, OutputInterface $output){
        $this->init();
        $output->writeln('Beginning sitemap generation');
        $output->writeln('Generating list of URLs...');
        $this->generateLinks();
        $output->writeln('Generating XML file...');
        $this->writeXML($this->links);
        $output->writeln('Complete!');
    }

    /*******************************************************/

    /*
     * Call all the functions here which should add links to the collection.
     * In each of the functions called you should look up necessary data from your data source
     * in order to generate the links for each page.
     */
    protected function generateLinks(){
      //below are a couple of example functions for setting links
      $this->getForumLinks();
      $this->getOtherLinks(); 
    }
    
    /*
     * This is an example function for settings links. Create more functions for each section 
     * of your site.
     */
    protected function getForumLinks(){
      //lookup data from your data source here to generate links
    }

    /*
     * This is an example function for settings links. Create more functions for each section 
     * of your site.
     */
    protected function getOtherLinks(){
      $this->links[] = array('loc'=>$this->generateURL('mysite_home'));
    }
    
    /*******************************************************/

    protected function writeXML($list){
      $this->initAppXmlObj();
      $this->updateXmlFile($list);
    }

    /**
     * Appends a row to a specific xml object
     *
     * @param SimpleXMLElement $xmlElement xml object for appending data
     * @param array $array row to add to the xml element
     * @return SimpleXMLElement
     */
    protected function addRow(SimpleXMLElement $xmlElement, array $array){
        $record = $xmlElement->addChild('url');
        //currently only sets 'loc', but the script could be easily adapted to add additional parameters
        $record->addChild('loc', htmlspecialchars($array['loc'])); 
        return $xmlElement;
    }

   /**
     * Updates the Xml object laying in SAVE_LOCATION
     *
     * @param $rows array an array of sitemap links
     */
    protected function updateXmlFile(array $rows){
        foreach ($rows as $rowArray) {
            $this->addRow($this->sitemapXml, $rowArray);
        }
        $dom = dom_import_simplexml($this->sitemapXml)->ownerDocument;
        $dom->formatOutput = true;
        file_put_contents($this->xmlOutputFile, $dom->saveXML());
    }

   /**
     * Initiates the appXml object
     * @param InputInterface $input
     */
    private function initAppXmlObj(){
        $this->sitemapXml = new SimpleXMLElement('<urlset/>');
        $this->sitemapXml->addAttribute('xmlns', 'http://www.sitemaps.org/schemas/sitemap/0.9');
        $this->xmlOutputFile = self::SAVE_LOCATION;
    }

    private function generateURL($route, $params=array()){
      return self::BASE_URL . $this->router->generate($route, $params);
    }
}