web/drupal/modules/xmlsitemap/xmlsitemap.pages.inc
branchdrupal
changeset 74 0ff3ba646492
equal deleted inserted replaced
73:fcf75e232c5b 74:0ff3ba646492
       
     1 <?php
       
     2 // $Id: xmlsitemap.pages.inc,v 1.1.4.4 2009/07/02 14:20:24 earnie Exp $
       
     3 
       
     4 
       
     5 /**
       
     6  * @file
       
     7  * XML sitemap page callbacks.
       
     8  */
       
     9 
       
    10 /**
       
    11  * @addtogroup xmlsitemap
       
    12  * @{
       
    13  */
       
    14 
       
    15 /*****************************************************************************
       
    16  * Menu callbacks / form builders, submit/validate functions.
       
    17  ****************************************************************************/
       
    18 
       
    19 /**
       
    20  * Menu callback; display the sitemap.
       
    21  *
       
    22  * @param $chunk
       
    23  *  An integer specifying which chunk of the sitemap is being requested.
       
    24  *  If not set and there is more than one chunk, display the sitemap index.
       
    25  */
       
    26 function xmlsitemap_output($chunk = NULL) {
       
    27   global $user;
       
    28   $chunk_size = variable_get('xmlsitemap_chunk_size', XMLSITEMAP_DEFAULT_SITEMAP_LINKS);
       
    29   $link_count = xmlsitemap_link_count();
       
    30   $chunk_count = xmlsitemap_chunk_count();
       
    31   // A sitemap may only have a set number of index links (links to other sitemap
       
    32   // files) and a set number of site links in each of the "other" sitemap files.
       
    33   // This code adjusts the number of site links specified by the user if the
       
    34   // set number of index links has been reached but will not set that number
       
    35   // greater than the set number of site links in a file.
       
    36   if ($chunk_count > XMLSITEMAP_MAX_SITEMAP_INDEX_LINKS &&
       
    37     $chunk_size < XMLSITEMAP_MAX_SITEMAP_LINKS) {
       
    38     // Determine the number of chunks we are over the maximum index links.
       
    39     $chunk_adjust = $chunk_count - XMLSITEMAP_MAX_SITEMAP_INDEX_LINKS;
       
    40     // Determine the number of links to adjust the chunk size.
       
    41     $chunk_adjust = $chunk_adjust * $chunk_size;
       
    42     if (($chunk_size + $chunk_adjust) <= XMLSITEMAP_MAX_SITEMAP_LINKS) {
       
    43       $chunk_size += $chunk_adjust;
       
    44     }
       
    45     else {
       
    46       $chunk_size = XMLSITEMAP_MAX_SITEMAP_LINKS;
       
    47     }
       
    48     variable_set('xmlsitemap_chunk_size', $chunk_size);
       
    49     watchdog('xmlsitemap', 'Chunk size has been updated to @chunk-size.', array('@chunk-size' => $chunk_size));
       
    50   }
       
    51   elseif($chunk_count > XMLSITEMAP_MAX_SITEMAP_INDEX_LINKS) {
       
    52     watchdog('xmlsitemap', 'The maximum number of allowed links has been reached.', NULL, WATCHDOG_ERROR);
       
    53   }
       
    54   if (isset($chunk) && !is_numeric($chunk)) {
       
    55     drupal_not_found();
       
    56     exit();
       
    57   }
       
    58   $id = xmlsitemap_language_id();
       
    59   if (variable_get('xmlsitemap_sitemap_needs_update', FALSE)) {
       
    60     variable_set('xmlsitemap_update_timestamp', REQUEST_TIME);
       
    61     db_query("DELETE FROM {xmlsitemap} WHERE type ='frontpage'");
       
    62     $row             = new stdClass();
       
    63     $row->module     = 'xmlsitemap';
       
    64     $row->type       = 'frontpage';
       
    65     $changefreq      = variable_get('xmlsitemap_front_page_changefreq', 3600);
       
    66     $row->changed    = REQUEST_TIME - $changefreq;
       
    67     $row->changefreq = $changefreq;
       
    68     $row->priority   = variable_get('xmlsitemap_front_page_priority', 1);
       
    69     drupal_write_record('xmlsitemap', $row);
       
    70     module_invoke_all('xmlsitemap_links');
       
    71     variable_set('xmlsitemap_sitemap_needs_update', FALSE);
       
    72     $result = _xmlsitemap_create_cache_files();
       
    73     if (variable_get("xmlsitemap_create_cache_result_$id", -1) !== $result) {
       
    74       variable_set("xmlsitemap_create_cache_result_$id", $result);
       
    75     }
       
    76   }
       
    77   elseif (_xmlsitemap_check_cache_files()) {
       
    78     $result = _xmlsitemap_create_cache_files();
       
    79     if (variable_get("xmlsitemap_create_cache_result_$id", -1) !== $result) {
       
    80       variable_set("xmlsitemap_create_cache_result_$id", $result);
       
    81     }
       
    82   }
       
    83   if (!isset($chunk)) {
       
    84     if (($chunks = (integer) $link_count / $chunk_size) != variable_get('xmlsitemap_previous_chunks_count', -1)) {
       
    85       variable_set('xmlsitemap_previous_chunks_count', $chunks);
       
    86       if (!variable_get('menu_rebuild_needed', FALSE)) {
       
    87         variable_set('menu_rebuild_needed', TRUE);
       
    88       }
       
    89     }
       
    90   }
       
    91   if (isset($result) && !$result) {
       
    92     drupal_not_found();
       
    93     exit();
       
    94   }
       
    95   $parent_directory = variable_get('xmlsitemap_cache_directory', file_directory_path() .'/xmlsitemap');
       
    96   $headers = array("Content-type: text/xml; charset=utf-8");
       
    97   if (isset($chunk)) {
       
    98     if ($chunk < $link_count / $chunk_size) {
       
    99       file_transfer("$parent_directory/xsm-$id-$chunk.xml", $headers);
       
   100     }
       
   101   }
       
   102   else {
       
   103     file_transfer("$parent_directory/xsm-$id.xml", $headers);
       
   104   }
       
   105 }
       
   106 
       
   107 /*****************************************************************************
       
   108  * Private functions.
       
   109  ****************************************************************************/
       
   110 
       
   111 /**
       
   112  * Check the cache files.
       
   113  *
       
   114  * @return
       
   115  *   TRUE if the cache files must be updated / created, FALSE otherwise.
       
   116  */
       
   117 function _xmlsitemap_check_cache_files() {
       
   118   $chunk_size       = variable_get('xmlsitemap_chunk_size', 1000);
       
   119   $link_count       = xmlsitemap_link_count();
       
   120   $id               = xmlsitemap_language_id();
       
   121   $parent_directory = variable_get('xmlsitemap_cache_directory', file_directory_path() .'/xmlsitemap');
       
   122   // If the directory that should contains the cache files doesn't exist, then
       
   123   // the cache files must be created.
       
   124   if (!file_check_directory($parent_directory, FILE_CREATE_DIRECTORY)) {
       
   125     return TRUE;
       
   126   }
       
   127   $update_timestamp = variable_get('xmlsitemap_update_timestamp', REQUEST_TIME);
       
   128   // If the cache files creation has failed last time, the cache files must be
       
   129   // created.
       
   130   if (variable_get("xmlsitemap_create_cache_result_$id", -1) !== TRUE) {
       
   131     return TRUE;
       
   132   }
       
   133   // If the main cache file doesn't exist, then the cache files must be
       
   134   // created.
       
   135   if (!file_exists($parent_directory ."/xsm-$id.xml")) {
       
   136     return TRUE;
       
   137   }
       
   138   // If the main cache file has been created before the sitemap content has
       
   139   // been updated, then the cache files must be updated.
       
   140   if (filemtime($parent_directory ."/xsm-$id.xml") < $update_timestamp) {
       
   141     return TRUE;
       
   142   }
       
   143   // Check also the other cache files.
       
   144   if ($link_count > $chunk_size) {
       
   145     for ($chunk = 0; $chunk < $link_count / $chunk_size; ++$chunk) {
       
   146       if (!file_exists($parent_directory ."/xsm-$id-$chunk.xml")) {
       
   147         return TRUE;
       
   148       }
       
   149       if (filemtime($parent_directory ."/xsm-$id-$chunk.xml") < $update_timestamp) {
       
   150         return TRUE;
       
   151       }
       
   152     }
       
   153   }
       
   154   return FALSE;
       
   155 }
       
   156 
       
   157 /**
       
   158  * Create a sitemap chunk cache file.
       
   159  *
       
   160  * @param $fp
       
   161  *  A file resource used to write in.
       
   162  * @param $chunk_size
       
   163  *  The number of links the chunk must cointain.
       
   164  * @param $chunk
       
   165  *  The progressive number associated with the sitemap chunk (starting from
       
   166  *  0).
       
   167  */
       
   168 function _xmlsitemap_create_cache_chunk($fp, $chunk_size, $chunk = 0) {
       
   169   fwrite($fp, '<?xml version="1.0" encoding="UTF-8"?>' . "\n");
       
   170   if ($xsl = _xmlsitemap_xsl()) {
       
   171     fwrite($fp, '<?xml-stylesheet type="text/xsl" href="' . $xsl . '" ?>' . "\n");
       
   172   }
       
   173   fwrite($fp, '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"' . "\n");
       
   174   fwrite($fp, '  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' . "\n");
       
   175   fwrite($fp, '  xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9' . "\n");
       
   176   fwrite($fp, '  http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">' . "\n");
       
   177   $start = $chunk * $chunk_size;
       
   178   $links = db_query_range("SELECT xsm.loc, xsm.module, xsm.type, xsm.id, xsm.sid, xsm.changed, xsm.changefreq, xsm.priority". xmlsitemap_sitemap_query() ."ORDER BY xsm.priority DESC, xsm.changed DESC, xsm.changefreq, xsm.loc", $start, $chunk_size);
       
   179   while ($link = db_fetch_object($links)) {
       
   180     if ($link->type == 'frontpage') {
       
   181       $url = url(NULL, array('absolute' => TRUE));
       
   182     }
       
   183     else {
       
   184       $url = url($link->loc, array('absolute' => TRUE));
       
   185     }
       
   186     $link->url = $url;
       
   187     if ($link->module && function_exists($link->module .'_xmlsitemap_link_status')) {
       
   188       $function = $link->module .'_xmlsitemap_link_status';
       
   189       $link->status = $function($link->type, $link->id, $link->sid);
       
   190     }
       
   191     else {
       
   192       $link->status = 0;
       
   193     }
       
   194     drupal_alter('xmlsitemap_data', $link);
       
   195     if (($link->status & XMLSITEMAP_LINK_DISABLED) != XMLSITEMAP_LINK_DISABLED) {
       
   196       fwrite($fp, '  <url>' . "\n");
       
   197       fwrite($fp, '    <loc>'. check_url($link->url) .'</loc>' . "\n");
       
   198       fwrite($fp, '    <lastmod>'. gmdate(DATE_W3C, $link->changed) .'</lastmod>' . "\n");
       
   199       fwrite($fp, '    <changefreq>'. xmlsitemap_sitemap_frequency($link->changefreq) .'</changefreq>' . "\n");
       
   200       fwrite($fp, '    <priority>'. number_format($link->priority, 1) .'</priority>' . "\n");
       
   201       fwrite($fp, '  </url>' . "\n");
       
   202     }
       
   203   }
       
   204   fwrite($fp, '</urlset>');
       
   205 }
       
   206 
       
   207 /**
       
   208  * Determine path for a xml stylesheet.
       
   209  *
       
   210  * @return
       
   211  * - The stylesheet path or FALSE.
       
   212  */
       
   213 function _xmlsitemap_xsl() {
       
   214   if (variable_get('xmlsitemap_use_stylesheet', FALSE)) {
       
   215     $paths = array(
       
   216       variable_get('xmlsitemap_cache_directory', file_directory_path() . '/xmlsitemap') . '/gss.xsl',
       
   217       drupal_get_path('module', 'xmlsitemap') . '/gss/gss.xsl',
       
   218     );
       
   219     foreach ($paths as $path) {
       
   220       if (file_exists($path)) {
       
   221         return base_path() . $path;
       
   222       }
       
   223     }
       
   224   }
       
   225   return FALSE;
       
   226 }
       
   227 
       
   228 /**
       
   229  * Create the cache files containing the sitemap.
       
   230  *
       
   231  * @return
       
   232  *  TRUE if the operation has been successfull, FALSE otherwise.
       
   233  */
       
   234 function _xmlsitemap_create_cache_files() {
       
   235   $chunk_size       = variable_get('xmlsitemap_chunk_size', 1000);
       
   236   $link_count       = xmlsitemap_link_count();
       
   237   $id               = xmlsitemap_language_id();
       
   238   $parent_directory = variable_get('xmlsitemap_cache_directory', file_directory_path() .'/xmlsitemap');
       
   239   // If the directory doesn't exist, then create it.
       
   240   if (!file_check_directory($parent_directory, FILE_CREATE_DIRECTORY)) {
       
   241     return TRUE;
       
   242   }
       
   243   if ($link_count > $chunk_size) {
       
   244     if (!$fp = fopen($parent_directory ."/xsm-$id.xml", 'wb')) {
       
   245       watchdog('xmlsitemap', 'Could not create the cache file @file.', array('@file' => $parent_directory ."/xsm-$id.xml"), WATCHDOG_ERROR);
       
   246       return FALSE;
       
   247     }
       
   248     fwrite($fp, '<?xml version="1.0" encoding="UTF-8"?>' . "\n");
       
   249     if ($xsl = _xmlsitemap_xsl()) {
       
   250       fwrite($fp, '<?xml-stylesheet type="text/xsl" href="' . $xsl . '" ?>' . "\n");
       
   251     }
       
   252     fwrite($fp, '<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"' . "\n");
       
   253     fwrite($fp, '  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' . "\n");
       
   254     fwrite($fp, '  xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9' . "\n");
       
   255     fwrite($fp, '  http://www.sitemaps.org/schemas/sitemap/0.9/siteindex.xsd">' . "\n");
       
   256     for ($chunk = 0; $chunk < $link_count / $chunk_size; ++$chunk) {
       
   257       fwrite($fp, '  <sitemap>' . "\n");
       
   258       fwrite($fp, '    <loc>'. url("sitemap$chunk.xml", array('absolute' => TRUE)) .'</loc>' . "\n");
       
   259       $from = $chunk * $chunk_size;
       
   260       $changed = db_result(db_query_range("SELECT xsm.changed". xmlsitemap_sitemap_query() ."ORDER BY xsm.priority DESC, xsm.changed DESC", $from, $chunk_size));
       
   261       fwrite($fp, '    <lastmod>'. gmdate(DATE_W3C, $changed) .'</lastmod>' . "\n");
       
   262       fwrite($fp, '  </sitemap>' . "\n");
       
   263     }
       
   264     fwrite($fp, '</sitemapindex>');
       
   265     fclose($fp);
       
   266     // Set standard file permissions for webserver-generated files.
       
   267     @chmod($parent_directory ."/xsm-$id.xml", 0664);
       
   268     for ($chunk = 0; $chunk < $link_count / $chunk_size; ++$chunk) {
       
   269       if (!$fp = fopen($parent_directory ."/xsm-$id-$chunk.xml", 'wb')) {
       
   270         watchdog('xmlsitemap', 'Could not create the cache file @file.', array('@file' => $parent_directory ."/xsm-$id-$chunk.xml"), WATCHDOG_ERROR);
       
   271         return FALSE;
       
   272       }
       
   273       _xmlsitemap_create_cache_chunk($fp, $chunk_size, $chunk);
       
   274       fclose($fp);
       
   275       // Set standard file permissions for webserver-generated files.
       
   276       @chmod($parent_directory ."/xsm-$id-$chunk.xml", 0664);
       
   277     }
       
   278   }
       
   279   else {
       
   280     if (!$fp = fopen($parent_directory ."/xsm-$id.xml", 'wb')) {
       
   281       watchdog('xmlsitemap', 'Could not create the cache file @file.', array('@file' => $parent_directory ."/xsm-$id.xml"), WATCHDOG_ERROR);
       
   282       return FALSE;
       
   283     }
       
   284     _xmlsitemap_create_cache_chunk($fp, $chunk_size);
       
   285     fclose($fp);
       
   286     // Set standard file permissions for webserver-generated files.
       
   287     @chmod($parent_directory ."/xsm-$id.xml", 0664);
       
   288   }
       
   289   return TRUE;
       
   290 }
       
   291 
       
   292 /**
       
   293  * @} End of "addtogroup xmlsitemap".
       
   294  */
       
   295