Want more features on Pastebin? Sign Up, it's FREE!
Guest

Untitled

By: a guest on Jul 2nd, 2012  |  syntax: PHP  |  size: 21.42 KB  |  views: 6  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. <?php
  2. /**
  3.  * @package XML_Sitemaps
  4.  */
  5.  
  6. class WPSEO_Sitemaps {
  7.         /**
  8.          * Content of the sitemap to output.
  9.          */
  10.         private $sitemap = '';
  11.  
  12.         /**
  13.          * Flag to indicate if this is an invalid or empty sitemap.
  14.          */
  15.         private $bad_sitemap = false;
  16.  
  17.         function __construct() {
  18.                 if ( !defined( 'ENT_XML1' ) )
  19.                         define( "ENT_XML1", 16 );
  20.  
  21.                 add_action( 'init', array( $this, 'init' ), 1 );
  22.                 add_action( 'template_redirect', array( $this, 'redirect' ) );
  23.                 add_filter( 'redirect_canonical', array( $this, 'canonical' ) );
  24.                 add_action( 'wpseo_hit_sitemap_index', array( $this, 'hit_sitemap_index' ) );
  25.                 add_action( 'wpseo_ping_search_engines', array( $this, 'ping_search_engines' ) );
  26.         }
  27.  
  28.         /**
  29.          * Register your own sitemap. Call this during 'init'.
  30.          *
  31.          * @param string   $name     The name of the sitemap
  32.          * @param callback $function Function to build your sitemap
  33.          * @param string   $rewrite  Optional. Regular expression to match your sitemap with
  34.          */
  35.         function register_sitemap( $name, $function, $rewrite = '' ) {
  36.                 add_action( 'wpseo_do_sitemap_' . $name, $function );
  37.                 if ( !empty( $rewrite ) )
  38.                         add_rewrite_rule( $rewrite, 'index.php?sitemap=' . $name, 'top' );
  39.         }
  40.  
  41.         /**
  42.          * Set the sitemap content to display after you have generated it.
  43.          *
  44.          * @param string $sitemap The generated sitemap to output
  45.          */
  46.         function set_sitemap( $sitemap ) {
  47.                 $this->sitemap = $sitemap;
  48.         }
  49.  
  50.         /**
  51.          * Set as true to make the request 404. Used stop the display of empty sitemaps or
  52.          * invalid requests.
  53.          *
  54.          * @param bool $bool Is this a bad request. True or false.
  55.          */
  56.         function set_bad_sitemap( $bool ) {
  57.                 $this->bad_sitemap = (bool) $bool;
  58.         }
  59.  
  60.         /**
  61.          * Initialize sitemaps. Add sitemap rewrite rules and query var
  62.          */
  63.         function init() {
  64.                 $GLOBALS['wp']->add_query_var( 'sitemap' );
  65.                 $GLOBALS['wp']->add_query_var( 'sitemap_n' );
  66.                 add_rewrite_rule( 'sitemap_index\.xml$', 'index.php?sitemap=1', 'top' );
  67.                 add_rewrite_rule( '([^/]+?)-sitemap([0-9]+)?\.xml$', 'index.php?sitemap=$matches[1]&sitemap_n=$matches[2]', 'top' );
  68.         }
  69.  
  70.         /**
  71.          * Hijack requests for potential sitemaps.
  72.          */
  73.         function redirect() {
  74.                 $type = get_query_var( 'sitemap' );
  75.                 if ( empty( $type ) )
  76.                         return;
  77.  
  78.                 $this->build_sitemap( $type );
  79.                 // 404 for invalid or emtpy sitemaps
  80.                 if ( $this->bad_sitemap ) {
  81.                         $GLOBALS['wp_query']->is_404 = true;
  82.                         return;
  83.                 }
  84.  
  85.                 $this->output();
  86.                 die();
  87.         }
  88.  
  89.         /**
  90.          * Attempt to build the requested sitemap. Sets $bad_sitemap if this isn't
  91.          * for the root sitemap, a post type or taxonomy.
  92.          *
  93.          * @param string $type The requested sitemap's identifier.
  94.          */
  95.         function build_sitemap( $type ) {
  96.                 $type = apply_filters( 'wpseo_build_sitemap_post_type', $type );
  97.  
  98.                 if ( $type == 1 )
  99.                         $this->build_root_map();
  100.                 else if ( post_type_exists( $type ) )
  101.                         $this->build_post_type_map( $type );
  102.                 else if ( $tax = get_taxonomy( $type ) )
  103.                         $this->build_tax_map( $tax );
  104.                 else if ( has_action( 'wpseo_do_sitemap_' . $type ) )
  105.                         do_action( 'wpseo_do_sitemap_' . $type );
  106.                 else
  107.                         $this->bad_sitemap = true;
  108.         }
  109.  
  110.         /**
  111.          * Build the root sitemap -- example.com/sitemap_index.xml -- which lists sub-sitemaps
  112.          * for other content types.
  113.          *
  114.          * @todo lastmod for sitemaps?
  115.          */
  116.  
  117.         function build_root_map() {
  118.                 global $wpdb;
  119.  
  120.                 $options = get_wpseo_options();
  121.  
  122.                 $this->sitemap = '<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . "\n";
  123.                 $base          = $GLOBALS['wp_rewrite']->using_index_permalinks() ? 'index.php/' : '';
  124.  
  125.                 // reference post type specific sitemaps
  126.                 foreach ( get_post_types( array( 'public' => true ) ) as $post_type ) {
  127.                         if ( $post_type == 'attachment' )
  128.                                 continue;
  129.  
  130.                         if ( isset( $options['post_types-' . $post_type . '-not_in_sitemap'] ) && $options['post_types-' . $post_type . '-not_in_sitemap'] )
  131.                                 continue;
  132.  
  133.                         $count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(ID) FROM $wpdb->posts WHERE post_type = %s AND post_status = 'publish' LIMIT 1", $post_type ) );
  134.                         // don't include post types with no posts
  135.                         if ( !$count )
  136.                                 continue;
  137.  
  138.                         $n = ( $count > 1000 ) ? (int) ceil( $count / 1000 ) : 1;
  139.                         for ( $i = 0; $i < $n; $i++ ) {
  140.                                 $count = ( $n > 1 ) ? $i + 1 : '';
  141.  
  142.                                 if ( empty( $count ) || $count == $n ) {
  143.                                         $date = $this->get_last_modified( $post_type );
  144.                                 } else {
  145.                                         $date = $wpdb->get_var( $wpdb->prepare( "SELECT post_modified_gmt FROM $wpdb->posts WHERE post_status = 'publish' AND post_type = %s ORDER BY post_modified_gmt ASC LIMIT 1 OFFSET %d", $post_type, $i * 1000 + 999 ) );
  146.                                         $date = date( 'c', strtotime( $date ) );
  147.                                 }
  148.  
  149.                                 $this->sitemap .= '<sitemap>' . "\n";
  150.                                 $this->sitemap .= '<loc>' . home_url( $base . $post_type . '-sitemap' . $count . '.xml' ) . '</loc>' . "\n";
  151.                                 $this->sitemap .= '<lastmod>' . htmlspecialchars( $date ) . '</lastmod>' . "\n";
  152.                                 $this->sitemap .= '</sitemap>' . "\n";
  153.                         }
  154.                 }
  155.  
  156.                 // reference taxonomy specific sitemaps
  157.                 foreach ( get_taxonomies( array( 'public' => true ) ) as $tax ) {
  158.                         if ( in_array( $tax, array( 'link_category', 'nav_menu', 'post_format' ) ) )
  159.                                 continue;
  160.  
  161.                         if ( isset( $options['taxonomies-' . $tax . '-not_in_sitemap'] ) && $options['taxonomies-' . $tax . '-not_in_sitemap'] )
  162.                                 continue;
  163.                         // don't include taxonomies with no terms
  164.                         if ( !$wpdb->get_var( $wpdb->prepare( "SELECT term_id FROM $wpdb->term_taxonomy WHERE taxonomy = %s AND count != 0 LIMIT 1", $tax ) ) )
  165.                                 continue;
  166.  
  167.                         // Retrieve the post_types that are registered to this taxonomy and then retrieve last modified date for all of those combined.
  168.                         $taxobj = get_taxonomy( $tax );
  169.                         $date   = $this->get_last_modified( $taxobj->object_type );
  170.  
  171.                         $this->sitemap .= '<sitemap>' . "\n";
  172.                         $this->sitemap .= '<loc>' . home_url( $base . $tax . '-sitemap.xml' ) . '</loc>' . "\n";
  173.                         $this->sitemap .= '<lastmod>' . htmlspecialchars( $date ) . '</lastmod>' . "\n";
  174.                         $this->sitemap .= '</sitemap>' . "\n";
  175.                 }
  176.  
  177.                 // allow other plugins to add their sitemaps to the index
  178.                 $this->sitemap .= apply_filters( 'wpseo_sitemap_index', '' );
  179.                 $this->sitemap .= '</sitemapindex>';
  180.  
  181.         }
  182.  
  183.         /**
  184.          * Build a sub-sitemap for a specific post type -- example.com/post_type-sitemap.xml
  185.          *
  186.          * @param string $post_type Registered post type's slug
  187.          */
  188.         function build_post_type_map( $post_type ) {
  189.                 $options = get_wpseo_options();
  190.  
  191.                 if (
  192.                         ( isset( $options['post_types-' . $post_type . '-not_in_sitemap'] ) && $options['post_types-' . $post_type . '-not_in_sitemap'] )
  193.                         || in_array( $post_type, array( 'revision', 'nav_menu_item', 'attachment' ) )
  194.                 ) {
  195.                         $this->bad_sitemap = true;
  196.                         return;
  197.                 }
  198.  
  199.                 $output = '';
  200.  
  201.                 $front_id = get_option( 'page_on_front' );
  202.                 if ( !$front_id && ( $post_type == 'post' || $post_type == 'page' ) ) {
  203.                         $output .= $this->sitemap_url( array(
  204.                                 'loc' => home_url( '/' ),
  205.                                 'pri' => 1,
  206.                                 'chf' => 'daily',
  207.                         ) );
  208.                 } else if ( $front_id && $post_type == 'post' ) {
  209.                         $page_for_posts = get_option( 'page_for_posts' );
  210.                         if ( $page_for_posts ) {
  211.                                 $output .= $this->sitemap_url( array(
  212.                                         'loc' => get_permalink( $page_for_posts ),
  213.                                         'pri' => 1,
  214.                                         'chf' => 'daily',
  215.                                 ) );
  216.                         }
  217.                 }
  218.  
  219.                 if ( function_exists( 'get_post_type_archive_link' ) ) {
  220.                         $archive = get_post_type_archive_link( $post_type );
  221.                         if ( $archive ) {
  222.                                 $output .= $this->sitemap_url( array(
  223.                                         'loc' => $archive,
  224.                                         'pri' => 0.8,
  225.                                         'chf' => 'weekly',
  226.                                         'mod' => $this->get_last_modified( $post_type ) // get_lastpostmodified( 'gmt', $post_type ) #17455
  227.                                 ) );
  228.                         }
  229.                 }
  230.  
  231.                 global $wpdb;
  232.  
  233.                 $join_filter  = '';
  234.                 $join_filter  = apply_filters( 'wpseo_typecount_join', $join_filter, $post_type );
  235.                 $where_filter = '';
  236.                 $where_filter = apply_filters( 'wpseo_typecount_where', $where_filter, $post_type );
  237.                 $typecount    = $wpdb->get_var( "SELECT COUNT(ID) FROM $wpdb->posts {$join_filter} WHERE post_status = 'publish' AND post_password = '' AND post_type = '$post_type' {$where_filter}" );
  238.  
  239.                 if ( $typecount == 0 && empty( $archive ) ) {
  240.                         $this->bad_sitemap = true;
  241.                         return;
  242.                 }
  243.  
  244.                 // Let's flush the object cache so we're not left with garbage from other plugins
  245.                 wp_cache_flush();
  246.  
  247.                 $stackedurls = array();
  248.  
  249.                 $steps  = 25;
  250.                 $n      = (int) get_query_var( 'sitemap_n' );
  251.                 $offset = ( $n > 1 ) ? ( $n - 1 ) * 1000 : 0;
  252.                 $total  = $offset + 1000;
  253.                 if ( $total > $typecount )
  254.                         $total = $typecount;
  255.  
  256.                 // We grab post_date, post_name, post_author and post_status too so we can throw these objects into get_permalink, which saves a get_post call for each permalink.
  257.                 while ( $total > $offset ) {
  258.  
  259.                         $join_filter  = apply_filters( 'wpseo_posts_join', '', $post_type );
  260.                         $where_filter = apply_filters( 'wpseo_posts_where', '', $post_type );
  261.  
  262.                         // Optimized query per this thread: http://wordpress.org/support/topic/plugin-wordpress-seo-by-yoast-performance-suggestion
  263.                         // Also see http://explainextended.com/2009/10/23/mysql-order-by-limit-performance-late-row-lookups/
  264.  
  265.                         $posts = $wpdb->get_results( "SELECT l.ID, post_content, post_name, post_author, post_parent, post_modified_gmt, post_date, post_date_gmt
  266.                         FROM (
  267.                                 SELECT ID FROM $wpdb->posts {$join_filter}
  268.                                                 WHERE post_status = 'publish'
  269.                                                 AND     post_password = ''
  270.                                                 AND post_type = '$post_type'
  271.                                                 {$where_filter}
  272.                                                 ORDER BY post_modified ASC
  273.                                                 LIMIT $steps OFFSET $offset ) o
  274.                         JOIN $wpdb->posts l
  275.                                 ON l.ID = o.ID
  276.                                 ORDER BY l.ID" );
  277.  
  278.                         /*                      $posts = $wpdb->get_results("SELECT ID, post_content, post_name, post_author, post_parent, post_modified_gmt, post_date, post_date_gmt
  279.                            FROM $wpdb->posts {$join_filter}
  280.                            WHERE post_status = 'publish'
  281.                            AND  post_password = ''
  282.                            AND post_type = '$post_type'
  283.                            {$where_filter}
  284.                            ORDER BY post_modified ASC
  285.                            LIMIT $steps OFFSET $offset"); */
  286.  
  287.                         $offset = $offset + $steps;
  288.  
  289.                         foreach ( $posts as $p ) {
  290.                                 $p->post_type   = $post_type;
  291.                                 $p->post_status = 'publish';
  292.                                 $p->filter      = 'sample';
  293.  
  294.                                 if ( wpseo_get_value( 'meta-robots-noindex', $p->ID ) && wpseo_get_value( 'sitemap-include', $p->ID ) != 'always' )
  295.                                         continue;
  296.                                 if ( wpseo_get_value( 'sitemap-include', $p->ID ) == 'never' )
  297.                                         continue;
  298.                                 if ( wpseo_get_value( 'redirect', $p->ID ) && strlen( wpseo_get_value( 'redirect', $p->ID ) ) > 0 )
  299.                                         continue;
  300.  
  301.                                 $url = array();
  302.  
  303.                                 $url['mod'] = ( isset( $p->post_modified_gmt ) && $p->post_modified_gmt != '0000-00-00 00:00:00' ) ? $p->post_modified_gmt : $p->post_date_gmt;
  304.                                 $url['chf'] = 'weekly';
  305.                                 $url['loc'] = get_permalink( $p );
  306.  
  307.                                 $canonical = wpseo_get_value( 'canonical', $p->ID );
  308.                                 if ( $canonical && $canonical != '' && $canonical != $url['loc'] ) {
  309.                                         // Let's assume that if a canonical is set for this page and it's different from the URL of this post, that page is either
  310.                                         // already in the XML sitemap OR is on an external site, either way, we shouldn't include it here.
  311.                                         continue;
  312.                                 } else {
  313.  
  314.                                         if ( isset( $options['trailingslash'] ) && $options['trailingslash'] && $p->post_type != 'post' )
  315.                                                 $url['loc'] = trailingslashit( $url['loc'] );
  316.                                 }
  317.  
  318.                                 $pri = wpseo_get_value( 'sitemap-prio', $p->ID );
  319.                                 if ( is_numeric( $pri ) )
  320.                                         $url['pri'] = $pri;
  321.                                 elseif ( $p->post_parent == 0 && $p->post_type == 'page' )
  322.                                         $url['pri'] = 0.8;
  323.                                 else
  324.                                         $url['pri'] = 0.6;
  325.  
  326.                                 if ( $p->ID == $front_id )
  327.                                         $url['pri'] = 1.0;
  328.  
  329.                                 $url['images'] = array();
  330.  
  331.                                 $content = $p->post_content;
  332.                                 if ( function_exists( 'get_the_post_thumbnail' ) ) {
  333.                                         $content = '<p>' . get_the_post_thumbnail( $p->ID, 'full' ) . '</p>' . $content;
  334.                                 }
  335.  
  336.                                 $host = str_replace( 'www.', '', parse_url( get_bloginfo( 'url' ), PHP_URL_HOST ) );
  337.  
  338.                                 if ( preg_match_all( '/<img [^>]+>/', $content, $matches ) ) {
  339.                                         foreach ( $matches[0] as $img ) {
  340.                                                 if ( preg_match( '/src=("|\')([^"|\']+)("|\')/', $img, $match ) ) {
  341.                                                         $src = $match[2];
  342.                                                         if ( strpos( $src, 'http' ) !== 0 ) {
  343.                                                                 if ( $src[0] != '/' )
  344.                                                                         continue;
  345.                                                                 $src = get_bloginfo( 'url' ) . $src;
  346.                                                         }
  347.  
  348.                                                         if ( strpos( $src, $host ) === false )
  349.                                                                 continue;
  350.  
  351.                                                         if ( $src != esc_url( $src ) )
  352.                                                                 continue;
  353.  
  354.                                                         if ( isset( $url['images'][$src] ) )
  355.                                                                 continue;
  356.  
  357.                                                         $image = array(
  358.                                                                 'src' => apply_filters( 'wpseo_xml_sitemap_img_src', $src, $p )
  359.                                                         );
  360.  
  361.                                                         if ( preg_match( '/title=("|\')([^"\']+)("|\')/', $img, $match ) )
  362.                                                                 $image['title'] = str_replace( array( '-', '_' ), ' ', $match[2] );
  363.  
  364.                                                         if ( preg_match( '/alt=("|\')([^"\']+)("|\')/', $img, $match ) )
  365.                                                                 $image['alt'] = str_replace( array( '-', '_' ), ' ', $match[2] );
  366.  
  367.                                                         $image = apply_filters( 'wpseo_xml_sitemap_img', $image, $p );
  368.  
  369.                                                         $url['images'][] = $image;
  370.                                                 }
  371.                                         }
  372.                                 }
  373.  
  374.                                 if ( preg_match_all( '/\[gallery/', $p->post_content, $matches ) ) {
  375.                                         $attachments = get_children( array( 'post_parent' => $p->ID, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image' ) );
  376.                                         foreach ( $attachments as $att_id => $attachment ) {
  377.                                                 $src   = wp_get_attachment_image_src( $att_id, 'large', false );
  378.                                                 $image = array(
  379.                                                         'src' => apply_filters( 'wpseo_xml_sitemap_img_src', $src[0], $p )
  380.                                                 );
  381.  
  382.                                                 if ( $alt = get_post_meta( $att_id, '_wp_attachment_image_alt', true ) )
  383.                                                         $image['alt'] = $alt;
  384.  
  385.                                                 $image['title'] = $attachment->post_title;
  386.  
  387.                                                 $image = apply_filters( 'wpseo_xml_sitemap_img', $image, $p );
  388.  
  389.                                                 $url['images'][] = $image;
  390.                                         }
  391.                                 }
  392.  
  393.                                 $url['images'] = apply_filters( 'wpseo_sitemap_urlimages', $url['images'], $p->ID );
  394.  
  395.                                 if ( !in_array( $url['loc'], $stackedurls ) ) {
  396.                                         $output .= $this->sitemap_url( $url );
  397.                                         $stackedurls[] = $url['loc'];
  398.                                 }
  399.  
  400.                                 // Clear the post_meta and the term cache for the post, as we no longer need it now.
  401.                                 wp_cache_delete( $p->ID, 'post_meta' );
  402.                                 // clean_object_term_cache( $p->ID, $post_type );
  403.                         }
  404.                 }
  405.  
  406.                 if ( empty( $output ) ) {
  407.                         $this->bad_sitemap = true;
  408.                         return;
  409.                 }
  410.  
  411.                 $this->sitemap = '<urlset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" ';
  412.                 $this->sitemap .= 'xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd" ';
  413.                 $this->sitemap .= 'xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . "\n";
  414.                 $this->sitemap .= $output;
  415.  
  416.                 // Filter to allow adding extra URLs, only do this on the first XML sitemap, not on all.
  417.                 if ( $n == 0 )
  418.                         $this->sitemap .= apply_filters( 'wpseo_sitemap_' . $post_type . '_content', '' );
  419.  
  420.                 $this->sitemap .= '</urlset>';
  421.         }
  422.  
  423.         /**
  424.          * Build a sub-sitemap for a specific taxonomy -- example.com/tax-sitemap.xml
  425.          *
  426.          * @param string $taxonomy Registered taxonomy's slug
  427.          */
  428.         function build_tax_map( $taxonomy ) {
  429.                 $options = get_wpseo_options();
  430.                 if (
  431.                         ( isset( $options['taxonomies-' . $taxonomy->name . '-not_in_sitemap'] ) && $options['taxonomies-' . $taxonomy->name . '-not_in_sitemap'] )
  432.                         || in_array( $taxonomy, array( 'link_category', 'nav_menu', 'post_format' ) )
  433.                 ) {
  434.                         $this->bad_sitemap = true;
  435.                         return;
  436.                 }
  437.  
  438.                 $terms = get_terms( $taxonomy->name, array( 'hide_empty' => true ) );
  439.  
  440.                 global $wpdb;
  441.                 $output = '';
  442.                 foreach ( $terms as $c ) {
  443.                         $url = array();
  444.  
  445.                         if ( wpseo_get_term_meta( $c, $c->taxonomy, 'noindex' )
  446.                                 && wpseo_get_term_meta( $c, $c->taxonomy, 'sitemap_include' ) != 'always'
  447.                         )
  448.                                 continue;
  449.  
  450.                         if ( wpseo_get_term_meta( $c, $c->taxonomy, 'sitemap_include' ) == 'never' )
  451.                                 continue;
  452.  
  453.                         $url['loc'] = wpseo_get_term_meta( $c, $c->taxonomy, 'canonical' );
  454.                         if ( !$url['loc'] ) {
  455.                                 $url['loc'] = get_term_link( $c, $c->taxonomy );
  456.                                 if ( isset( $options['trailingslash'] ) && $options['trailingslash'] )
  457.                                         $url['loc'] = trailingslashit( $url['loc'] );
  458.                         }
  459.                         if ( $c->count > 10 ) {
  460.                                 $url['pri'] = 0.6;
  461.                         } else if ( $c->count > 3 ) {
  462.                                 $url['pri'] = 0.4;
  463.                         } else {
  464.                                 $url['pri'] = 0.2;
  465.                         }
  466.  
  467.                         // Grab last modified date
  468.                         $sql        = "SELECT MAX(p.post_date) AS lastmod
  469.                                         FROM    $wpdb->posts AS p
  470.                                         INNER JOIN $wpdb->term_relationships AS term_rel
  471.                                         ON              term_rel.object_id = p.ID
  472.                                         INNER JOIN $wpdb->term_taxonomy AS term_tax
  473.                                         ON              term_tax.term_taxonomy_id = term_rel.term_taxonomy_id
  474.                                         AND             term_tax.taxonomy = '$c->taxonomy'
  475.                                         AND             term_tax.term_id = $c->term_id
  476.                                         WHERE   p.post_status = 'publish'
  477.                                         AND             p.post_password = ''";
  478.                         $url['mod'] = $wpdb->get_var( $sql );
  479.                         $url['chf'] = 'weekly';
  480.                         $output .= $this->sitemap_url( $url );
  481.                 }
  482.  
  483.                 if ( empty( $output ) ) {
  484.                         $this->bad_sitemap = true;
  485.                         return;
  486.                 }
  487.  
  488.                 $this->sitemap = '<urlset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ';
  489.                 $this->sitemap .= 'xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd" ';
  490.                 $this->sitemap .= 'xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . "\n";
  491.                 $this->sitemap .= $output . '</urlset>';
  492.         }
  493.  
  494.         /**
  495.          * Spit out the generated sitemap and relevant headers and encoding information.
  496.          */
  497.         function output() {
  498.                 // Prevent the search engines from indexing the XML Sitemap.
  499.                 header( 'X-Robots-Tag: noindex, follow', true );
  500.  
  501.                 header( 'Content-Type: text/xml' );
  502.                 echo '<?xml version="1.0" encoding="' . get_bloginfo( 'charset' ) . '"?>';
  503.                 echo $this->sitemap;
  504.                 echo "\n" . '<!-- XML Sitemap generated by Yoast WordPress SEO -->';
  505.  
  506.                 if ( WP_DEBUG )
  507.                         echo "\n" . '<!-- Built in ' . timer_stop() . ' seconds | ' . memory_get_peak_usage() . ' | ' . count( $GLOBALS['wpdb']->queries ) . ' -->';
  508.         }
  509.  
  510.         /**
  511.          * Build the <url> tag for a given URL.
  512.          *
  513.          * @param array $url Array of parts that make up this entry
  514.          * @return string
  515.          */
  516.         function sitemap_url( $url ) {
  517.                 if ( isset( $url['mod'] ) )
  518.                         $date = mysql2date( "Y-m-d\TH:i:s+00:00", $url['mod'] );
  519.                 else
  520.                         $date = date( 'c' );
  521.                 $output = "\t<url>\n";
  522.                 $output .= "\t\t<loc>" . $url['loc'] . "</loc>\n";
  523.                 $output .= "\t\t<lastmod>" . $date . "</lastmod>\n";
  524.                 $output .= "\t\t<changefreq>" . $url['chf'] . "</changefreq>\n";
  525.                 $output .= "\t\t<priority>" . str_replace( ',', '.', $url['pri'] ) . "</priority>\n";
  526.                 if ( isset( $url['images'] ) && count( $url['images'] ) > 0 ) {
  527.                         foreach ( $url['images'] as $img ) {
  528.                                 $output .= "\t\t<image:image>\n";
  529.                                 $output .= "\t\t\t<image:loc>" . esc_html( $img['src'] ) . "</image:loc>\n";
  530.                                 if ( isset( $img['title'] ) )
  531.                                         $output .= "\t\t\t<image:title>" . _wp_specialchars( html_entity_decode( $img['title'], ENT_QUOTES, get_bloginfo('charset') ) ) . "</image:title>\n";
  532.                                 if ( isset( $img['alt'] ) )
  533.                                         $output .= "\t\t\t<image:caption>" . _wp_specialchars( html_entity_decode( $img['alt'], ENT_QUOTES, get_bloginfo('charset') ) ) . "</image:caption>\n";
  534.                                 $output .= "\t\t</image:image>\n";
  535.                         }
  536.                 }
  537.                 $output .= "\t</url>\n";
  538.                 return $output;
  539.         }
  540.  
  541.         /**
  542.          * Notify search engines of the updated sitemap.
  543.          */
  544.         function ping_search_engines() {
  545.                 $options    = get_option( 'wpseo_xml' );
  546.                 $base       = $GLOBALS['wp_rewrite']->using_index_permalinks() ? 'index.php/' : '';
  547.                 $sitemapurl = urlencode( home_url( $base . 'sitemap_index.xml' ) );
  548.  
  549.                 // Always ping Google and Bing, optionally ping Ask and Yahoo!
  550.                 wp_remote_get( 'http://www.google.com/webmasters/tools/ping?sitemap=' . $sitemapurl );
  551.                 wp_remote_get( 'http://www.bing.com/webmaster/ping.aspx?sitemap=' . $sitemapurl );
  552.  
  553.                 if ( isset( $options['xml_ping_yahoo'] ) && $options['xml_ping_yahoo'] )
  554.                         wp_remote_get( 'http://search.yahooapis.com/SiteExplorerService/V1/updateNotification?appid=3usdTDLV34HbjQpIBuzMM1UkECFl5KDN7fogidABihmHBfqaebDuZk1vpLDR64I-&url=' . $sitemapurl );
  555.  
  556.                 if ( isset( $options['xml_ping_ask'] ) && $options['xml_ping_ask'] )
  557.                         wp_remote_get( 'http://submissions.ask.com/ping?sitemap=' . $sitemapurl );
  558.         }
  559.  
  560.         /**
  561.          * Make a request for the sitemap index so as to cache it before the arrival of the search engines.
  562.          */
  563.         function hit_sitemap_index() {
  564.                 $base = $GLOBALS['wp_rewrite']->using_index_permalinks() ? 'index.php/' : '';
  565.                 $url  = home_url( $base . 'sitemap_index.xml' );
  566.                 wp_remote_get( $url );
  567.         }
  568.  
  569.         /**
  570.          * Hook into redirect_canonical to stop trailing slashes on sitemap.xml URLs
  571.          *
  572.          * @param string $redirect The redirect URL currently determined.
  573.          * @return bool|string $redirect
  574.          */
  575.         function canonical( $redirect ) {
  576.                 $sitemap = get_query_var( 'sitemap' );
  577.                 if ( !empty( $sitemap ) )
  578.                         return false;
  579.  
  580.                 return $redirect;
  581.         }
  582.  
  583.         /**
  584.          * Get the modification date for the last modified post in the post type:
  585.          *
  586.          * @param array $post_types Post types to get the last modification date for
  587.          * @return string
  588.          */
  589.         function get_last_modified( $post_types ) {
  590.                 global $wpdb;
  591.                 if ( !is_array( $post_types ) )
  592.                         $post_types = array( $post_types );
  593.  
  594.                 $result = 0;
  595.                 foreach ( $post_types as $post_type ) {
  596.                         $key  = 'lastpostmodified:gmt:' . $post_type;
  597.                         $date = wp_cache_get( $key, 'timeinfo' );
  598.                         if ( !$date ) {
  599.                                 $date = $wpdb->get_var( $wpdb->prepare( "SELECT post_modified_gmt FROM $wpdb->posts WHERE post_status = 'publish' AND post_type = %s ORDER BY post_modified_gmt DESC LIMIT 1", $post_type ) );
  600.                                 if ( $date )
  601.                                         wp_cache_set( $key, $date, 'timeinfo' );
  602.                         }
  603.                         if ( strtotime( $date ) > $result )
  604.                                 $result = strtotime( $date );
  605.                 }
  606.  
  607.                 // Transform to W3C Date format.
  608.                 $result = date( 'c', $result );
  609.                 return $result;
  610.         }
  611. }
  612.  
  613. global $wpseo_sitemaps;
  614. $wpseo_sitemaps = new WPSEO_Sitemaps();
clone this paste RAW Paste Data