[ Index ]

PHP Cross Reference of DokuWiki

title

Body

[close]

/inc/Sitemap/ -> Mapper.php (source)

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