*/
if(!defined('DOKU_INC')) die('meh.');
class Sitemapper {
/**
* Builds a Google Sitemap of all public pages known to the indexer
*
* The map is placed in the cache directory named sitemap.xml.gz - This
* file needs to be writable!
*
* @author Andreas Gohr
* @link https://www.google.com/webmasters/sitemaps/docs/en/about.html
*/
public function generate(){
global $conf;
dbglog('sitemapGenerate(): started');
if(!$conf['sitemap']) return false;
$sitemap = Sitemapper::getFilePath();
dbglog("runSitemapper(): using $sitemap");
if(@file_exists($sitemap)){
if(!is_writable($sitemap)) return false;
}else{
if(!is_writable(dirname($sitemap))) return false;
}
if(@filesize($sitemap) &&
@filemtime($sitemap) > (time()-($conf['sitemap']*60*60*24))){
dbglog('runSitemapper(): Sitemap up to date');
return false;
}
$pages = idx_getIndex('page', '');
dbglog('runSitemapper(): creating sitemap using '.count($pages).' pages');
$items = array();
// build the sitemap items
foreach($pages as $id){
//skip hidden, non existing and restricted files
if(isHiddenPage($id)) continue;
if(auth_aclcheck($id,'','') < AUTH_READ) continue;
$items[] = SitemapItem::createFromID($id);
}
$eventData = array('items' => &$items, 'sitemap' => &$sitemap);
$event = new Doku_Event('SITEMAP_GENERATE', $eventData);
if ($event->advise_before(true)) {
//save the new sitemap
$result = io_saveFile($sitemap, Sitemapper::getXML($items));
}
$event->advise_after();
return $result;
}
private function getXML($items) {
ob_start();
print ''.NL;
print ''.NL;
foreach ($items as $item) {
print $item->toXML();
}
print ''.NL;
$result = ob_get_contents();
ob_end_clean();
return $result;
}
public function getFilePath() {
global $conf;
$sitemap = $conf['cachedir'].'/sitemap.xml';
if($conf['compression'] == 'bz2' || $conf['compression'] == 'gz'){
$sitemap .= '.gz';
}
return $sitemap;
}
public function pingSearchEngines() {
//ping search engines...
$http = new DokuHTTPClient();
$http->timeout = 8;
$encoded_sitemap_url = urlencode(wl('', array('do' => 'sitemap'), true, '&'));
$ping_urls = array(
'google' => 'http://www.google.com/webmasters/sitemaps/ping?sitemap='.$encoded_sitemap_url,
'yahoo' => 'http://search.yahooapis.com/SiteExplorerService/V1/updateNotification?appid=dokuwiki&url='.$encoded_sitemap_url,
'microsoft' => 'http://www.bing.com/webmaster/ping.aspx?siteMap='.$encoded_sitemap_url,
);
$event = new Doku_Event('SITEMAP_PING', $ping_urls);
if ($event->advise_before(true)) {
foreach ($ping_urls as $name => $url) {
dbglog("sitemapPingSearchEngines(): pinging $name");
$resp = $http->get($url);
if($http->error) dbglog("runSitemapper(): $http->error");
dbglog('runSitemapper(): '.preg_replace('/[\n\r]/',' ',strip_tags($resp)));
}
}
$event->advise_after();
return true;
}
}
class SitemapItem {
public $url;
public $lastmod;
public $changefreq;
public $priority;
public function __construct($url, $lastmod, $changefreq = null, $priority = null) {
$this->url = $url;
$this->lastmod = $lastmod;
$this->changefreq = $changefreq;
$this->priority = $priority;
}
public static function createFromID($id, $changefreq = null, $priority = null) {
$id = trim($id);
$date = @filemtime(wikiFN($id));
if(!$date) return NULL;
return new SitemapItem(wl($id, '', true), $date, $changefreq, $priority);
}
public function toXML() {
$result = ' '.NL;
$result .= ' '.hsc($this->url).''.NL;
$result .= ' '.date_iso8601($this->lastmod).''.NL;
if ($this->changefreq !== NULL)
$result .= ' '.hsc($this->changefreq).''.NL;
if ($this->priority !== NULL)
$result .= ' '.hsc($this->priority).''.NL;
$result .= ' '.NL;
return $result;
}
}