<?php
/**
 * Sitemap Generator Class
 * 
 * @author Alex Zhukoff
 * @license http://creativecommons.org/licenses/by-sa/3.0/ (Creative Commons BY-SA)
 * @version 1.0
 * @link http://zhukoff.com
 */

class SitemapGenerator {

	private $fsitemap = 'sitemap.xml';
	public $schema = 'http://www.google.com/schemas/sitemap/0.84';
	public $pingstat = 'failed';
	private $dbh = null;
	private $val = null;
	private $del = null;
	public $freq = array("always","hourly","daily","weekly","monthly","yearly","never");


	/**
	 * SitemapGenerator constructor
	 * @param string $fsitemap
	 * @param string $schema
	 */
	function __construct($fsitemap = null, $schema = null){
		$this->schema = !$schema ? $this->schema : $schema;
		$this->cPDO('localhost','mysql','db','root','');
		if(!is_file($this->fsitemap))$this->createSM();
	}


	/**
	 * DB connection
	 * @param string $h host
	 * @param string $s dns
	 * @param string $db database
	 * @param string $u user
	 * @param string $p pass
	 * @access private
	   */
	private function cPDO($h = '127.0.0.1',$s = 'mysql',$db = 'db',$u = 'root',$p = ''){
		$this->dbh = new PDO($s.':dbname='.$db.';host='.$h, $u, $p);
	}


	/**
	 * DB connection
	 * @access private
	   */
	private function createSM(){
		file_put_contents($this->fsitemap,$this->wrap());
		$this->del = 1;
	}


		/**
	 * Sitemap file header
	 * @access private
	   */
	private function wrap(){
		return '<?xml version="1.0" encoding="UTF-8"?>'."\n".
				'<urlset xmlns="'.$this->schema.'">'."\n".
				'</urlset>';
	}


	/**
	 * "Add links" wrapper
	 * @param mixed $val Could be either an array or an string
	   */
	public function addLinks($val = null){
		try{$this->pAdd($val);}
		catch(Exception $x){echo $x->getMessage();}
	}


	/**
	 * Add links
	 * @param mixed $val Could be either an array or an string
	 * @access private
	   */
	private function pAdd($val){
		if((@$val) && !is_array(@$val)){$this->val = array($val);}
		elseif(@$val[0][0] != null){$this->val = $val;}
		else{throw new Exception("Не передано ни одной ссылки");}

		$load = simplexml_load_file($this->fsitemap);
		foreach($this->val as $v){
			$tm = $load->addChild('url');
			if($this->chkAdd('lnk',$v[0]))$tm->addChild('loc', $v[0]);
			if($this->chkAdd('lmd',$v[1]))$tm->addChild('lastmod', $v[1]);
			if($this->chkAdd('chf',$v[2]))$tm->addChild('changefreq', $v[2]);
			if($v[3] = $this->chkAdd('pri',$v[3]))$tm->addChild('priority', $v[3]);
		}
		$tmp = $load->asXML();
		file_put_contents($this->fsitemap, $tmp);
		$this->del = null;
		unset($tmp);
	}


	/**
	 * Check links
	 * @param string $t
	 * @param mixed $v Could be either an string or an int
	 * @return mixed Could be an string or an int or null
	   */
	public function chkAdd($t,$v){
		switch ($t){
		case 'lnk':return utf8_encode(htmlentities($v,ENT_QUOTES,"UTF-8"));
		case 'lmd':return ($v == '')?null:$v;
		case 'chf':return array_keys($this->freq, $v);
		case 'pri':return ($v == '')?null:$this->priorIt($v);
		}
	}


	/**
	 * Correct priority
	 * @param int $v
	 * @return int
	   */
	public function priorIt($v){
		$v = $v > 1?'1':$v;
		$v = $v < 0?'0.1':$v;
		return $v;
	}


	/**
	 * Send message to search engine
	 * @param string $sm_ping
	 * @param string $sm_url
	   */
	public function pingSE($sm_ping = null, $sm_url = null){
		try{
			$ping = $sm_ping.urlencode($sm_url);
			$c = curl_init();
			curl_setopt($c, CURLOPT_URL, $ping);
			curl_setopt($c, CURLOPT_HEADER, 1);
			curl_setopt($c, CURLOPT_NOBODY, 1);
			curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
			curl_setopt($c, CURLOPT_FRESH_CONNECT, 1);
			if (!curl_exec($c)) {throw new Exception("Не удалось установить соединение с сервером");}
			$httpcode = curl_getinfo($c, CURLINFO_HTTP_CODE);
			echo ($httpcode == 200)?'Отправлено уведомление':'Не удалось отправить уведомление';
			$this->pingstat = ($httpcode == 200)?'done':'failed';
		}catch(Exception $x){echo $x->getMessage();}
}


	/**
	 * SitemapGenerator destructor
	   */
	function __destruct(){
		if($this->del){unlink($this->fsitemap);}
		$log['date'] = date("Y-m-d");
		$log['links'] = serialize($this->val);
		$log['ping'] = $this->pingstat;
		try{$this->dbh->exec("INSERT INTO n VALUES ('{$log['date']}', '{$log['links']}', '{$log['ping']}')");}
		catch(Exception $x){echo "Не могу выполнить запрос";}
		}
}
?>
