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