http location to final sitemap file, fileName -> full server path to sitemap file, _appid -> yahoo! api id //sure this can be cleaned up - but for the point of it - do whatever you need. //this is a generic reproduction of the wordpress google sitemap generator - not intended for actual out-of-the-box use. //$gen = new GoogleSitemapGenerator(); //$gen->BuildSitemap(); //TODO - you need snoopy for pings require_once('class-snoopy.php'); //error_reporting(E_ALL); //ini_set("display_errors",1); //@ini_set("memory_limit",''); /** * Represents an item in the page list * @author Arne Brachhold * @package sitemap * @since 3.0 */ class GoogleSitemapGeneratorPage { /** * @var string $_url Sets the URL or the relative path to the blog dir of the page * @access private */ var $_url; /** * @var float $_priority Sets the priority of this page * @access private */ var $_priority; /** * @var string $_changeFreq Sets the change frequency of the page. I want Enums! * @access private */ var $_changeFreq; /** * @var int $_lastMod Sets the lastMod date as a UNIX timestamp. * @access private */ var $_lastMod; /** * Initialize a new page object * * @since 3.0 * @access public * @author Arne Brachhold * @param bool $enabled Should this page be included in thesitemap * @param string $url The URL or path of the file * @param float $priority The Priority of the page 0.0 to 1.0 * @param string $changeFreq The change frequency like daily, hourly, weekly * @param int $lastMod The last mod date as a unix timestamp */ function GoogleSitemapGeneratorPage($url="",$priority=0.0,$changeFreq="never",$lastMod=0) { $this->SetUrl($url); $this->SetProprity($priority); $this->SetChangeFreq($changeFreq); $this->SetLastMod($lastMod); } /** * Returns the URL of the page * * @return string The URL */ function GetUrl() { return $this->_url; } /** * Sets the URL of the page * * @param string $url The new URL */ function SetUrl($url) { $this->_url=(string) $url; } /** * Returns the priority of this page * * @return float the priority, from 0.0 to 1.0 */ function GetPriority() { return $this->_priority; } /** * Sets the priority of the page * * @param float $priority The new priority from 0.1 to 1.0 */ function SetProprity($priority) { $this->_priority=floatval($priority); } /** * Returns the change frequency of the page * * @return string The change frequncy like hourly, weekly, monthly etc. */ function GetChangeFreq() { return $this->_changeFreq; } /** * Sets the change frequency of the page * * @param string $changeFreq The new change frequency */ function SetChangeFreq($changeFreq) { $this->_changeFreq=(string) $changeFreq; } /** * Returns the last mod of the page * * @return int The lastmod value in seconds */ function GetLastMod() { return $this->_lastMod; } /** * Sets the last mod of the page * * @param int $lastMod The lastmod of the page */ function SetLastMod($lastMod) { $this->_lastMod=intval($lastMod); } function Render() { if($this->_url == "/" || empty($this->_url)) return ''; $r=""; $r.= "\t\n"; $r.= "\t\t" . $this->EscapeXML($this->_url) . "\n"; if($this->_lastMod>0) $r.= "\t\t" . date('Y-m-d\TH:i:s+00:00',$this->_lastMod) . "\n"; if(!empty($this->_changeFreq)) $r.= "\t\t" . $this->_changeFreq . "\n"; if($this->_priority!==false && $this->_priority!=="") $r.= "\t\t" . number_format($this->_priority,1) . "\n"; $r.= "\t\n"; return $r; } function EscapeXML($string) { return str_replace ( array ( '&', '"', "'", '<', '>'), array ( '&' , '"', ''' , '<' , '>'), $string); } } class GoogleSitemapGeneratorXmlEntry { var $_xml; function GoogleSitemapGeneratorXmlEntry($xml) { $this->_xml = $xml; } function Render() { return $this->_xml; } } class GoogleSitemapGeneratorDebugEntry extends GoogleSitemapGeneratorXmlEntry { function Render() { return "\n"; } } /** * Class to generate a sitemaps.org Sitemaps compliant sitemap of a WordPress blog. * * @package sitemap * @author Arne Brachhold * @since 3.0 */ class GoogleSitemapGenerator { /** * @var string Holds the last error if one occurs when writing the files */ var $_lastError=null; /** * @var object The file handle which is used to write the sitemap file */ var $_fileHandle = null; /** * @var object The file handle which is used to write the zipped sitemap file */ var $_fileZipHandle = null; /** * @var string $_appid Sets the Yahoo! appid * @access private */ var $_appid = null; //but you sould probably set this to something of value from yahoo! /** * Initializes a new Google Sitemap Generator * * @since 3.0 * @access private * @author Arne Brachhold */ function GoogleSitemapGenerator() { } /** * Returns if the compressed sitemap was activated * * @since 3.0b8 * @access private * @author Arne Brachhold * @return true if compressed */ function IsGzipEnabled() { return (function_exists("gzwrite")); } /** * Adds a url to the sitemap. You can use this method or call AddElement directly. * * @since 3.0 * @access public * @author Arne Brachhold * @param $loc string The location (url) of the page * @param $lastMod int The last Modification time as a UNIX timestamp * @param $changeFreq string The change frequenty of the page, Valid values are "always", "hourly", "daily", "weekly", "monthly", "yearly" and "never". * @param $priorty float The priority of the page, between 0.0 and 1.0 * @see AddElement * @return string The URL node */ function AddUrl($loc, $lastMod = 0, $changeFreq = "monthly", $priority = 0.5) { $page = new GoogleSitemapGeneratorPage($loc, $priority, $changeFreq, $lastMod); $this->AddElement($page); } /** * Adds an element to the sitemap * * @since 3.0 * @access private * @author Arne Brachhold * @param $page The element */ function AddElement(&$page) { if(empty($page)) return; $s = $page->Render(); if($this->_fileZipHandle && $this->IsGzipEnabled()) { gzwrite($this->_fileZipHandle,$s); } if($this->_fileHandle) { fwrite($this->_fileHandle,$s); } } /** * Checks if a file is writable and tries to make it if not. * * @since 3.05b * @access private * @author VJTD3 * @return bool true if writable */ function IsFileWritable($filename) { //can we write? if(!is_writable($filename)) { //no we can't. if(!@chmod($filename, 0666)) { $pathtofilename = dirname($filename); //Lets check if parent directory is writable. if(!is_writable($pathtofilename)) { //it's not writeable too. if(!@chmod($pathtoffilename, 0666)) { //darn couldn't fix up parrent directory this hosting is foobar. //Lets error because of the permissions problems. return false; } } } } //we can write, return 1/true/happy dance. return true; } /** * Builds the sitemap and writes it into a xml file. * * ATTENTION PLUGIN DEVELOPERS! DONT CALL THIS METHOD DIRECTLY! * The method is probably not available, since it is only loaded when needed. * Use do_action("sm_rebuild"); if you want to rebuild the sitemap. * Please refer to the documentation.txt for more details. * * @since 3.0 * @access public * @author Arne Brachhold * @return array An array with messages such as failed writes etc. */ function BuildSitemap() { echo '

Generic PHP Sitemap Generator

'; //TODO - set a pingurl -> location of sitemap file *.gz if using* $pingUrl = "http://http/domain/to/xyzsitemap.xml.gz"; //TODO - set full path to file location $fileName = '/foo/bar/full/path/to/xyzsitemap.xml'; echo ("
Generating file: ". $fileName); //check if file is there if($this->IsFileWritable($fileName)) { $this->_fileHandle = fopen($fileName,"w"); if(!$this->_fileHandle) echo "
ERROR: xml Not openable\n"; } else echo "
ERROR: xml file not writable\n"; //Write gzipped sitemap file if($this->IsGzipEnabled()) { $gzfileName = $fileName . '.gz'; if($this->IsFileWritable($gzfileName)) { $this->_fileZipHandle = gzopen($gzfileName,"w1"); if(!$this->_fileZipHandle) echo "
ERROR: gzip Not openable\n"; } else echo "
ERROR: gzip not writable\n"; } if(!$this->_fileHandle && !$this->_fileZipHandle) { echo "
ERROR: ending - no filehandle\n"; return; } //BEGIN SITEMAP //Content of the XML file $this->AddElement(new GoogleSitemapGeneratorXmlEntry('')); $this->AddElement(new GoogleSitemapGeneratorDebugEntry("generator=\"etiviti\"")); $this->AddElement(new GoogleSitemapGeneratorDebugEntry("sitemap-generator-url=\"http://etiviti.com\" sitemap-generator-version=\"1.0\"")); //TODO - add your generation timestamp $this->AddElement(new GoogleSitemapGeneratorDebugEntry("generated-on=\"\"")); $this->AddElement(new GoogleSitemapGeneratorXmlEntry('')); //SITEMAP MEAT AND POTATOES - db calls, loops, etc to actually generate sitemap url data goes here. $this->AddUrl("http://foo/bar/html/page/", 'htmldatetimestamp', 'daily', '0.7'); //SITEMAP MEAT AND POTATOES //CLOSE SITEMAP $this->AddElement(new GoogleSitemapGeneratorXmlEntry("")); if($this->_fileHandle && fclose($this->_fileHandle)) { $this->_fileHandle = null; } else echo "
ERROR: xml Could not close the sitemap file."; if($this->IsGzipEnabled()) { if($this->_fileZipHandle && fclose($this->_fileZipHandle)) { $this->_fileZipHandle = null; } else echo "
ERROR: gzip Could not close the zipped sitemap file"; } //SEND PINGS echo '

PINGS

'; //Ping Google $sPingUrl="http://www.google.com/webmasters/sitemaps/ping?sitemap=" . urlencode($pingUrl); echo '
PING: google: ' . $sPingUrl; $pingres=$this->RemoteOpen($sPingUrl); if($pingres==NULL || $pingres===false) { echo '
PING: google' . $this->_lastError; trigger_error("Failed to ping Google: " . htmlspecialchars(strip_tags($pingres)),E_USER_NOTICE); } else { echo '
PING: google - end'; } //Ping Ask.com $sPingUrl="http://submissions.ask.com/ping?sitemap=" . urlencode($pingUrl); echo '
PING: ask: ' . $sPingUrl; $pingres=$this->RemoteOpen($sPingUrl); if($pingres==NULL || $pingres===false || strpos($pingres,"successfully received and added")===false) { //Ask.com returns 200 OK even if there was an error, so we need to check the content. echo 'pinging ask' . $this->_lastError; trigger_error("Failed to ping Ask.com: " . htmlspecialchars(strip_tags($pingres)),E_USER_NOTICE); } else { echo '
PING: pinging ask - end'; } if ($this->_appid != null) { //Ping YAHOO $sPingUrl="http://search.yahooapis.com/SiteExplorerService/V1/updateNotification?appid=". $this->_appid ."&url=" . urlencode($pingUrl); echo '
PING: yahoo: ' . $sPingUrl; $pingres=$this->RemoteOpen($sPingUrl); if($pingres==NULL || $pingres===false || strpos(strtolower($pingres),"success")===false) { trigger_error("Failed to ping YAHOO: " . htmlspecialchars(strip_tags($pingres)),E_USER_NOTICE); echo '
PING: yahoo: ' . $this->_lastError; } else { echo '
PING: yahoo - end'; } } //Ping Bing $sPingUrl="http://www.bing.com/webmaster/ping.aspx?siteMap=" . urlencode($pingUrl); echo '
PING: bing' . $sPingUrl; $pingres=$this->RemoteOpen($sPingUrl); if($pingres==NULL || $pingres===false || strpos($pingres,"Thanks for submitting your sitemap")===false) { trigger_error("Failed to ping Bing: " . htmlspecialchars(strip_tags($pingres)),E_USER_NOTICE); echo '
PING: bing' . $this->_lastError; } else { echo '
PING: bing - end'; } echo '
generating sitemap complete'; //done... return true; } /** * Opens a remote file using Snoopy * @since 3.0 * @param $url The URL to open * @param $method get or post * @param $postData An array with key=>value paris * @param $timeout Timeout for the request, by default 10 * @return mixed False on error, the body of the response on success */ function RemoteOpen($url,$method = 'get', $postData = null, $timeout = 10) { $s = new Snoopy(); $s->read_timeout = $timeout; if($method == 'get') { $s->fetch($url); } else { $s->submit($url,$postData); } if($s->status != "200") { trigger_error('Snoopy Web Request failed: Status: ' . $s->status . "; Content: " . htmlspecialchars($s->results),E_USER_NOTICE); } return $s->results; } /** * Converts a mysql datetime value into a unix timestamp * * @param The value in the mysql datetime format * @return int The time in seconds */ function GetTimestampFromMySql($mysqlDateTime) { list($date, $hours) = split(' ', $mysqlDateTime); list($year,$month,$day) = split('-',$date); list($hour,$min,$sec) = split(':',$hours); return mktime(intval($hour), intval($min), intval($sec), intval($month), intval($day), intval($year)); } }