1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
|
<?php
/**
* Sitemap handling functions
*
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
* @author Michael Hamann <michael@content-space.de>
*/
namespace dokuwiki\Sitemap;
use dokuwiki\HTTP\DokuHTTPClient;
use dokuwiki\Logger;
/**
* A class for building sitemaps and pinging search engines with the sitemap URL.
*
* @author Michael Hamann
*/
class Mapper {
/**
* 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 Michael Hamann
* @author Andreas Gohr
* @link https://www.google.com/webmasters/sitemaps/docs/en/about.html
* @link http://www.sitemaps.org/
*
* @return bool
*/
public static function generate(){
global $conf;
if($conf['sitemap'] < 1 || !is_numeric($conf['sitemap'])) return false;
$sitemap = Mapper::getFilePath();
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']*86400))){ // 60*60*24=86400
Logger::debug('Sitemapper::generate(): Sitemap up to date');
return false;
}
Logger::debug("Sitemapper::generate(): using $sitemap");
$pages = idx_get_indexer()->getPages();
Logger::debug('Sitemapper::generate(): 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,'',array()) < AUTH_READ) continue;
$item = Item::createFromID($id);
if ($item !== null)
$items[] = $item;
}
$eventData = array('items' => &$items, 'sitemap' => &$sitemap);
$event = new \dokuwiki\Extension\Event('SITEMAP_GENERATE', $eventData);
if ($event->advise_before(true)) {
//save the new sitemap
$event->result = io_saveFile($sitemap, Mapper::getXML($items));
}
$event->advise_after();
return $event->result;
}
/**
* Builds the sitemap XML string from the given array auf SitemapItems.
*
* @param $items array The SitemapItems that shall be included in the sitemap.
* @return string The sitemap XML.
*
* @author Michael Hamann
*/
private static function getXML($items) {
ob_start();
echo '<?xml version="1.0" encoding="UTF-8"?>'.NL;
echo '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">'.NL;
foreach ($items as $item) {
/** @var Item $item */
echo $item->toXML();
}
echo '</urlset>'.NL;
$result = ob_get_contents();
ob_end_clean();
return $result;
}
/**
* Helper function for getting the path to the sitemap file.
*
* @return string The path to the sitemap file.
*
* @author Michael Hamann
*/
public static function getFilePath() {
global $conf;
$sitemap = $conf['cachedir'].'/sitemap.xml';
if (self::sitemapIsCompressed()) {
$sitemap .= '.gz';
}
return $sitemap;
}
/**
* Helper function for checking if the sitemap is compressed
*
* @return bool If the sitemap file is compressed
*/
public static function sitemapIsCompressed() {
global $conf;
return $conf['compression'] === 'bz2' || $conf['compression'] === 'gz';
}
/**
* Pings search engines with the sitemap url. Plugins can add or remove
* urls to ping using the SITEMAP_PING event.
*
* @author Michael Hamann
*
* @return bool
*/
public static function pingSearchEngines() {
//ping search engines...
$http = new DokuHTTPClient();
$http->timeout = 8;
$encoded_sitemap_url = urlencode(wl('', array('do' => 'sitemap'), true, '&'));
$ping_urls = array(
'google' => 'https://www.google.com/ping?sitemap='.$encoded_sitemap_url,
'microsoft' => 'http://www.bing.com/webmaster/ping.aspx?siteMap='.$encoded_sitemap_url,
'yandex' => 'https://webmaster.yandex.com/ping?sitemap='.$encoded_sitemap_url
);
$data = array('ping_urls' => $ping_urls,
'encoded_sitemap_url' => $encoded_sitemap_url
);
$event = new \dokuwiki\Extension\Event('SITEMAP_PING', $data);
if ($event->advise_before(true)) {
foreach ($data['ping_urls'] as $name => $url) {
Logger::debug("Sitemapper::PingSearchEngines(): pinging $name");
$resp = $http->get($url);
if($http->error) {
Logger::debug("Sitemapper:pingSearchengines(): $http->error", $resp);
}
}
}
$event->advise_after();
return true;
}
}
|