home *** CD-ROM | disk | FTP | other *** search
/ HTML Examples / WP.iso / wordpress2 / wp-admin / includes / export.php < prev    next >
Encoding:
PHP Script  |  2017-06-26  |  22.4 KB  |  622 lines

  1. <?php
  2. /**
  3.  * WordPress Export Administration API
  4.  *
  5.  * @package WordPress
  6.  * @subpackage Administration
  7.  */
  8.  
  9. /**
  10.  * Version number for the export format.
  11.  *
  12.  * Bump this when something changes that might affect compatibility.
  13.  *
  14.  * @since 2.5.0
  15.  */
  16. define( 'WXR_VERSION', '1.2' );
  17.  
  18. /**
  19.  * Generates the WXR export file for download.
  20.  *
  21.  * Default behavior is to export all content, however, note that post content will only
  22.  * be exported for post types with the `can_export` argument enabled. Any posts with the
  23.  * 'auto-draft' status will be skipped.
  24.  *
  25.  * @since 2.1.0
  26.  *
  27.  * @global wpdb    $wpdb WordPress database abstraction object.
  28.  * @global WP_Post $post Global `$post`.
  29.  *
  30.  * @param array $args {
  31.  *     Optional. Arguments for generating the WXR export file for download. Default empty array.
  32.  *
  33.  *     @type string $content        Type of content to export. If set, only the post content of this post type
  34.  *                                  will be exported. Accepts 'all', 'post', 'page', 'attachment', or a defined
  35.  *                                  custom post. If an invalid custom post type is supplied, every post type for
  36.  *                                  which `can_export` is enabled will be exported instead. If a valid custom post
  37.  *                                  type is supplied but `can_export` is disabled, then 'posts' will be exported
  38.  *                                  instead. When 'all' is supplied, only post types with `can_export` enabled will
  39.  *                                  be exported. Default 'all'.
  40.  *     @type string $author         Author to export content for. Only used when `$content` is 'post', 'page', or
  41.  *                                  'attachment'. Accepts false (all) or a specific author ID. Default false (all).
  42.  *     @type string $category       Category (slug) to export content for. Used only when `$content` is 'post'. If
  43.  *                                  set, only post content assigned to `$category` will be exported. Accepts false
  44.  *                                  or a specific category slug. Default is false (all categories).
  45.  *     @type string $start_date     Start date to export content from. Expected date format is 'Y-m-d'. Used only
  46.  *                                  when `$content` is 'post', 'page' or 'attachment'. Default false (since the
  47.  *                                  beginning of time).
  48.  *     @type string $end_date       End date to export content to. Expected date format is 'Y-m-d'. Used only when
  49.  *                                  `$content` is 'post', 'page' or 'attachment'. Default false (latest publish date).
  50.  *     @type string $status         Post status to export posts for. Used only when `$content` is 'post' or 'page'.
  51.  *                                  Accepts false (all statuses except 'auto-draft'), or a specific status, i.e.
  52.  *                                  'publish', 'pending', 'draft', 'auto-draft', 'future', 'private', 'inherit', or
  53.  *                                  'trash'. Default false (all statuses except 'auto-draft').
  54.  * }
  55.  */
  56. function export_wp( $args = array() ) {
  57.     global $wpdb, $post;
  58.  
  59.     $defaults = array( 'content' => 'all', 'author' => false, 'category' => false,
  60.         'start_date' => false, 'end_date' => false, 'status' => false,
  61.     );
  62.     $args = wp_parse_args( $args, $defaults );
  63.  
  64.     /**
  65.      * Fires at the beginning of an export, before any headers are sent.
  66.      *
  67.      * @since 2.3.0
  68.      *
  69.      * @param array $args An array of export arguments.
  70.      */
  71.     do_action( 'export_wp', $args );
  72.  
  73.     $sitename = sanitize_key( get_bloginfo( 'name' ) );
  74.     if ( ! empty( $sitename ) ) {
  75.         $sitename .= '.';
  76.     }
  77.     $date = date( 'Y-m-d' );
  78.     $wp_filename = $sitename . 'wordpress.' . $date . '.xml';
  79.     /**
  80.      * Filters the export filename.
  81.      *
  82.      * @since 4.4.0
  83.      *
  84.      * @param string $wp_filename The name of the file for download.
  85.      * @param string $sitename    The site name.
  86.      * @param string $date        Today's date, formatted.
  87.      */
  88.     $filename = apply_filters( 'export_wp_filename', $wp_filename, $sitename, $date );
  89.  
  90.     header( 'Content-Description: File Transfer' );
  91.     header( 'Content-Disposition: attachment; filename=' . $filename );
  92.     header( 'Content-Type: text/xml; charset=' . get_option( 'blog_charset' ), true );
  93.  
  94.     if ( 'all' != $args['content'] && post_type_exists( $args['content'] ) ) {
  95.         $ptype = get_post_type_object( $args['content'] );
  96.         if ( ! $ptype->can_export )
  97.             $args['content'] = 'post';
  98.  
  99.         $where = $wpdb->prepare( "{$wpdb->posts}.post_type = %s", $args['content'] );
  100.     } else {
  101.         $post_types = get_post_types( array( 'can_export' => true ) );
  102.         $esses = array_fill( 0, count($post_types), '%s' );
  103.         $where = $wpdb->prepare( "{$wpdb->posts}.post_type IN (" . implode( ',', $esses ) . ')', $post_types );
  104.     }
  105.  
  106.     if ( $args['status'] && ( 'post' == $args['content'] || 'page' == $args['content'] ) )
  107.         $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_status = %s", $args['status'] );
  108.     else
  109.         $where .= " AND {$wpdb->posts}.post_status != 'auto-draft'";
  110.  
  111.     $join = '';
  112.     if ( $args['category'] && 'post' == $args['content'] ) {
  113.         if ( $term = term_exists( $args['category'], 'category' ) ) {
  114.             $join = "INNER JOIN {$wpdb->term_relationships} ON ({$wpdb->posts}.ID = {$wpdb->term_relationships}.object_id)";
  115.             $where .= $wpdb->prepare( " AND {$wpdb->term_relationships}.term_taxonomy_id = %d", $term['term_taxonomy_id'] );
  116.         }
  117.     }
  118.  
  119.     if ( 'post' == $args['content'] || 'page' == $args['content'] || 'attachment' == $args['content'] ) {
  120.         if ( $args['author'] )
  121.             $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_author = %d", $args['author'] );
  122.  
  123.         if ( $args['start_date'] )
  124.             $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_date >= %s", date( 'Y-m-d', strtotime($args['start_date']) ) );
  125.  
  126.         if ( $args['end_date'] )
  127.             $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_date < %s", date( 'Y-m-d', strtotime('+1 month', strtotime($args['end_date'])) ) );
  128.     }
  129.  
  130.     // Grab a snapshot of post IDs, just in case it changes during the export.
  131.     $post_ids = $wpdb->get_col( "SELECT ID FROM {$wpdb->posts} $join WHERE $where" );
  132.  
  133.     /*
  134.      * Get the requested terms ready, empty unless posts filtered by category
  135.      * or all content.
  136.      */
  137.     $cats = $tags = $terms = array();
  138.     if ( isset( $term ) && $term ) {
  139.         $cat = get_term( $term['term_id'], 'category' );
  140.         $cats = array( $cat->term_id => $cat );
  141.         unset( $term, $cat );
  142.     } elseif ( 'all' == $args['content'] ) {
  143.         $categories = (array) get_categories( array( 'get' => 'all' ) );
  144.         $tags = (array) get_tags( array( 'get' => 'all' ) );
  145.  
  146.         $custom_taxonomies = get_taxonomies( array( '_builtin' => false ) );
  147.         $custom_terms = (array) get_terms( $custom_taxonomies, array( 'get' => 'all' ) );
  148.  
  149.         // Put categories in order with no child going before its parent.
  150.         while ( $cat = array_shift( $categories ) ) {
  151.             if ( $cat->parent == 0 || isset( $cats[$cat->parent] ) )
  152.                 $cats[$cat->term_id] = $cat;
  153.             else
  154.                 $categories[] = $cat;
  155.         }
  156.  
  157.         // Put terms in order with no child going before its parent.
  158.         while ( $t = array_shift( $custom_terms ) ) {
  159.             if ( $t->parent == 0 || isset( $terms[$t->parent] ) )
  160.                 $terms[$t->term_id] = $t;
  161.             else
  162.                 $custom_terms[] = $t;
  163.         }
  164.  
  165.         unset( $categories, $custom_taxonomies, $custom_terms );
  166.     }
  167.  
  168.     /**
  169.      * Wrap given string in XML CDATA tag.
  170.      *
  171.      * @since 2.1.0
  172.      *
  173.      * @param string $str String to wrap in XML CDATA tag.
  174.      * @return string
  175.      */
  176.     function wxr_cdata( $str ) {
  177.         if ( ! seems_utf8( $str ) ) {
  178.             $str = utf8_encode( $str );
  179.         }
  180.         // $str = ent2ncr(esc_html($str));
  181.         $str = '<![CDATA[' . str_replace( ']]>', ']]]]><![CDATA[>', $str ) . ']]>';
  182.  
  183.         return $str;
  184.     }
  185.  
  186.     /**
  187.      * Return the URL of the site
  188.      *
  189.      * @since 2.5.0
  190.      *
  191.      * @return string Site URL.
  192.      */
  193.     function wxr_site_url() {
  194.         // Multisite: the base URL.
  195.         if ( is_multisite() )
  196.             return network_home_url();
  197.         // WordPress (single site): the blog URL.
  198.         else
  199.             return get_bloginfo_rss( 'url' );
  200.     }
  201.  
  202.     /**
  203.      * Output a cat_name XML tag from a given category object
  204.      *
  205.      * @since 2.1.0
  206.      *
  207.      * @param object $category Category Object
  208.      */
  209.     function wxr_cat_name( $category ) {
  210.         if ( empty( $category->name ) )
  211.             return;
  212.  
  213.         echo '<wp:cat_name>' . wxr_cdata( $category->name ) . "</wp:cat_name>\n";
  214.     }
  215.  
  216.     /**
  217.      * Output a category_description XML tag from a given category object
  218.      *
  219.      * @since 2.1.0
  220.      *
  221.      * @param object $category Category Object
  222.      */
  223.     function wxr_category_description( $category ) {
  224.         if ( empty( $category->description ) )
  225.             return;
  226.  
  227.         echo '<wp:category_description>' . wxr_cdata( $category->description ) . "</wp:category_description>\n";
  228.     }
  229.  
  230.     /**
  231.      * Output a tag_name XML tag from a given tag object
  232.      *
  233.      * @since 2.3.0
  234.      *
  235.      * @param object $tag Tag Object
  236.      */
  237.     function wxr_tag_name( $tag ) {
  238.         if ( empty( $tag->name ) )
  239.             return;
  240.  
  241.         echo '<wp:tag_name>' . wxr_cdata( $tag->name ) . "</wp:tag_name>\n";
  242.     }
  243.  
  244.     /**
  245.      * Output a tag_description XML tag from a given tag object
  246.      *
  247.      * @since 2.3.0
  248.      *
  249.      * @param object $tag Tag Object
  250.      */
  251.     function wxr_tag_description( $tag ) {
  252.         if ( empty( $tag->description ) )
  253.             return;
  254.  
  255.         echo '<wp:tag_description>' . wxr_cdata( $tag->description ) . "</wp:tag_description>\n";
  256.     }
  257.  
  258.     /**
  259.      * Output a term_name XML tag from a given term object
  260.      *
  261.      * @since 2.9.0
  262.      *
  263.      * @param object $term Term Object
  264.      */
  265.     function wxr_term_name( $term ) {
  266.         if ( empty( $term->name ) )
  267.             return;
  268.  
  269.         echo '<wp:term_name>' . wxr_cdata( $term->name ) . "</wp:term_name>\n";
  270.     }
  271.  
  272.     /**
  273.      * Output a term_description XML tag from a given term object
  274.      *
  275.      * @since 2.9.0
  276.      *
  277.      * @param object $term Term Object
  278.      */
  279.     function wxr_term_description( $term ) {
  280.         if ( empty( $term->description ) )
  281.             return;
  282.  
  283.         echo "\t\t<wp:term_description>" . wxr_cdata( $term->description ) . "</wp:term_description>\n";
  284.     }
  285.  
  286.     /**
  287.      * Output term meta XML tags for a given term object.
  288.      *
  289.      * @since 4.6.0
  290.      *
  291.      * @param WP_Term $term Term object.
  292.      */
  293.     function wxr_term_meta( $term ) {
  294.         global $wpdb;
  295.  
  296.         $termmeta = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->termmeta WHERE term_id = %d", $term->term_id ) );
  297.  
  298.         foreach ( $termmeta as $meta ) {
  299.             /**
  300.              * Filters whether to selectively skip term meta used for WXR exports.
  301.              *
  302.              * Returning a truthy value to the filter will skip the current meta
  303.              * object from being exported.
  304.              *
  305.              * @since 4.6.0
  306.              *
  307.              * @param bool   $skip     Whether to skip the current piece of term meta. Default false.
  308.              * @param string $meta_key Current meta key.
  309.              * @param object $meta     Current meta object.
  310.              */
  311.             if ( ! apply_filters( 'wxr_export_skip_termmeta', false, $meta->meta_key, $meta ) ) {
  312.                 printf( "\t\t<wp:termmeta>\n\t\t\t<wp:meta_key>%s</wp:meta_key>\n\t\t\t<wp:meta_value>%s</wp:meta_value>\n\t\t</wp:termmeta>\n", wxr_cdata( $meta->meta_key ), wxr_cdata( $meta->meta_value ) );
  313.             }
  314.         }
  315.     }
  316.  
  317.     /**
  318.      * Output list of authors with posts
  319.      *
  320.      * @since 3.1.0
  321.      *
  322.      * @global wpdb $wpdb WordPress database abstraction object.
  323.      *
  324.      * @param array $post_ids Array of post IDs to filter the query by. Optional.
  325.      */
  326.     function wxr_authors_list( array $post_ids = null ) {
  327.         global $wpdb;
  328.  
  329.         if ( !empty( $post_ids ) ) {
  330.             $post_ids = array_map( 'absint', $post_ids );
  331.             $and = 'AND ID IN ( ' . implode( ', ', $post_ids ) . ')';
  332.         } else {
  333.             $and = '';
  334.         }
  335.  
  336.         $authors = array();
  337.         $results = $wpdb->get_results( "SELECT DISTINCT post_author FROM $wpdb->posts WHERE post_status != 'auto-draft' $and" );
  338.         foreach ( (array) $results as $result )
  339.             $authors[] = get_userdata( $result->post_author );
  340.  
  341.         $authors = array_filter( $authors );
  342.  
  343.         foreach ( $authors as $author ) {
  344.             echo "\t<wp:author>";
  345.             echo '<wp:author_id>' . intval( $author->ID ) . '</wp:author_id>';
  346.             echo '<wp:author_login>' . wxr_cdata( $author->user_login ) . '</wp:author_login>';
  347.             echo '<wp:author_email>' . wxr_cdata( $author->user_email ) . '</wp:author_email>';
  348.             echo '<wp:author_display_name>' . wxr_cdata( $author->display_name ) . '</wp:author_display_name>';
  349.             echo '<wp:author_first_name>' . wxr_cdata( $author->first_name ) . '</wp:author_first_name>';
  350.             echo '<wp:author_last_name>' . wxr_cdata( $author->last_name ) . '</wp:author_last_name>';
  351.             echo "</wp:author>\n";
  352.         }
  353.     }
  354.  
  355.     /**
  356.      * Output all navigation menu terms
  357.      *
  358.      * @since 3.1.0
  359.      */
  360.     function wxr_nav_menu_terms() {
  361.         $nav_menus = wp_get_nav_menus();
  362.         if ( empty( $nav_menus ) || ! is_array( $nav_menus ) )
  363.             return;
  364.  
  365.         foreach ( $nav_menus as $menu ) {
  366.             echo "\t<wp:term>";
  367.             echo '<wp:term_id>' . intval( $menu->term_id ) . '</wp:term_id>';
  368.             echo '<wp:term_taxonomy>nav_menu</wp:term_taxonomy>';
  369.             echo '<wp:term_slug>' . wxr_cdata( $menu->slug ) . '</wp:term_slug>';
  370.             wxr_term_name( $menu );
  371.             echo "</wp:term>\n";
  372.         }
  373.     }
  374.  
  375.     /**
  376.      * Output list of taxonomy terms, in XML tag format, associated with a post
  377.      *
  378.      * @since 2.3.0
  379.      */
  380.     function wxr_post_taxonomy() {
  381.         $post = get_post();
  382.  
  383.         $taxonomies = get_object_taxonomies( $post->post_type );
  384.         if ( empty( $taxonomies ) )
  385.             return;
  386.         $terms = wp_get_object_terms( $post->ID, $taxonomies );
  387.  
  388.         foreach ( (array) $terms as $term ) {
  389.             echo "\t\t<category domain=\"{$term->taxonomy}\" nicename=\"{$term->slug}\">" . wxr_cdata( $term->name ) . "</category>\n";
  390.         }
  391.     }
  392.  
  393.     /**
  394.      *
  395.      * @param bool   $return_me
  396.      * @param string $meta_key
  397.      * @return bool
  398.      */
  399.     function wxr_filter_postmeta( $return_me, $meta_key ) {
  400.         if ( '_edit_lock' == $meta_key )
  401.             $return_me = true;
  402.         return $return_me;
  403.     }
  404.     add_filter( 'wxr_export_skip_postmeta', 'wxr_filter_postmeta', 10, 2 );
  405.  
  406.     echo '<?xml version="1.0" encoding="' . get_bloginfo('charset') . "\" ?>\n";
  407.  
  408.     ?>
  409. <!-- This is a WordPress eXtended RSS file generated by WordPress as an export of your site. -->
  410. <!-- It contains information about your site's posts, pages, comments, categories, and other content. -->
  411. <!-- You may use this file to transfer that content from one site to another. -->
  412. <!-- This file is not intended to serve as a complete backup of your site. -->
  413.  
  414. <!-- To import this information into a WordPress site follow these steps: -->
  415. <!-- 1. Log in to that site as an administrator. -->
  416. <!-- 2. Go to Tools: Import in the WordPress admin panel. -->
  417. <!-- 3. Install the "WordPress" importer from the list. -->
  418. <!-- 4. Activate & Run Importer. -->
  419. <!-- 5. Upload this file using the form provided on that page. -->
  420. <!-- 6. You will first be asked to map the authors in this export file to users -->
  421. <!--    on the site. For each author, you may choose to map to an -->
  422. <!--    existing user on the site or to create a new user. -->
  423. <!-- 7. WordPress will then import each of the posts, pages, comments, categories, etc. -->
  424. <!--    contained in this file into your site. -->
  425.  
  426. <?php the_generator( 'export' ); ?>
  427. <rss version="2.0"
  428.     xmlns:excerpt="http://wordpress.org/export/<?php echo WXR_VERSION; ?>/excerpt/"
  429.     xmlns:content="http://purl.org/rss/1.0/modules/content/"
  430.     xmlns:wfw="http://wellformedweb.org/CommentAPI/"
  431.     xmlns:dc="http://purl.org/dc/elements/1.1/"
  432.     xmlns:wp="http://wordpress.org/export/<?php echo WXR_VERSION; ?>/"
  433. >
  434.  
  435. <channel>
  436.     <title><?php bloginfo_rss( 'name' ); ?></title>
  437.     <link><?php bloginfo_rss( 'url' ); ?></link>
  438.     <description><?php bloginfo_rss( 'description' ); ?></description>
  439.     <pubDate><?php echo date( 'D, d M Y H:i:s +0000' ); ?></pubDate>
  440.     <language><?php bloginfo_rss( 'language' ); ?></language>
  441.     <wp:wxr_version><?php echo WXR_VERSION; ?></wp:wxr_version>
  442.     <wp:base_site_url><?php echo wxr_site_url(); ?></wp:base_site_url>
  443.     <wp:base_blog_url><?php bloginfo_rss( 'url' ); ?></wp:base_blog_url>
  444.  
  445. <?php wxr_authors_list( $post_ids ); ?>
  446.  
  447. <?php foreach ( $cats as $c ) : ?>
  448.     <wp:category>
  449.         <wp:term_id><?php echo intval( $c->term_id ); ?></wp:term_id>
  450.         <wp:category_nicename><?php echo wxr_cdata( $c->slug ); ?></wp:category_nicename>
  451.         <wp:category_parent><?php echo wxr_cdata( $c->parent ? $cats[$c->parent]->slug : '' ); ?></wp:category_parent>
  452.         <?php wxr_cat_name( $c );
  453.         wxr_category_description( $c );
  454.         wxr_term_meta( $c ); ?>
  455.     </wp:category>
  456. <?php endforeach; ?>
  457. <?php foreach ( $tags as $t ) : ?>
  458.     <wp:tag>
  459.         <wp:term_id><?php echo intval( $t->term_id ); ?></wp:term_id>
  460.         <wp:tag_slug><?php echo wxr_cdata( $t->slug ); ?></wp:tag_slug>
  461.         <?php wxr_tag_name( $t );
  462.         wxr_tag_description( $t );
  463.         wxr_term_meta( $t ); ?>
  464.     </wp:tag>
  465. <?php endforeach; ?>
  466. <?php foreach ( $terms as $t ) : ?>
  467.     <wp:term>
  468.         <wp:term_id><?php echo wxr_cdata( $t->term_id ); ?></wp:term_id>
  469.         <wp:term_taxonomy><?php echo wxr_cdata( $t->taxonomy ); ?></wp:term_taxonomy>
  470.         <wp:term_slug><?php echo wxr_cdata( $t->slug ); ?></wp:term_slug>
  471.         <wp:term_parent><?php echo wxr_cdata( $t->parent ? $terms[$t->parent]->slug : '' ); ?></wp:term_parent>
  472.         <?php wxr_term_name( $t );
  473.         wxr_term_description( $t );
  474.         wxr_term_meta( $t ); ?>
  475.     </wp:term>
  476. <?php endforeach; ?>
  477. <?php if ( 'all' == $args['content'] ) wxr_nav_menu_terms(); ?>
  478.  
  479.     <?php
  480.     /** This action is documented in wp-includes/feed-rss2.php */
  481.     do_action( 'rss2_head' );
  482.     ?>
  483.  
  484. <?php if ( $post_ids ) {
  485.     /**
  486.      * @global WP_Query $wp_query
  487.      */
  488.     global $wp_query;
  489.  
  490.     // Fake being in the loop.
  491.     $wp_query->in_the_loop = true;
  492.  
  493.     // Fetch 20 posts at a time rather than loading the entire table into memory.
  494.     while ( $next_posts = array_splice( $post_ids, 0, 20 ) ) {
  495.     $where = 'WHERE ID IN (' . join( ',', $next_posts ) . ')';
  496.     $posts = $wpdb->get_results( "SELECT * FROM {$wpdb->posts} $where" );
  497.  
  498.     // Begin Loop.
  499.     foreach ( $posts as $post ) {
  500.         setup_postdata( $post );
  501.         $is_sticky = is_sticky( $post->ID ) ? 1 : 0;
  502. ?>
  503.     <item>
  504.         <title><?php
  505.             /** This filter is documented in wp-includes/feed.php */
  506.             echo apply_filters( 'the_title_rss', $post->post_title );
  507.         ?></title>
  508.         <link><?php the_permalink_rss() ?></link>
  509.         <pubDate><?php echo mysql2date( 'D, d M Y H:i:s +0000', get_post_time( 'Y-m-d H:i:s', true ), false ); ?></pubDate>
  510.         <dc:creator><?php echo wxr_cdata( get_the_author_meta( 'login' ) ); ?></dc:creator>
  511.         <guid isPermaLink="false"><?php the_guid(); ?></guid>
  512.         <description></description>
  513.         <content:encoded><?php
  514.             /**
  515.              * Filters the post content used for WXR exports.
  516.              *
  517.              * @since 2.5.0
  518.              *
  519.              * @param string $post_content Content of the current post.
  520.              */
  521.             echo wxr_cdata( apply_filters( 'the_content_export', $post->post_content ) );
  522.         ?></content:encoded>
  523.         <excerpt:encoded><?php
  524.             /**
  525.              * Filters the post excerpt used for WXR exports.
  526.              *
  527.              * @since 2.6.0
  528.              *
  529.              * @param string $post_excerpt Excerpt for the current post.
  530.              */
  531.             echo wxr_cdata( apply_filters( 'the_excerpt_export', $post->post_excerpt ) );
  532.         ?></excerpt:encoded>
  533.         <wp:post_id><?php echo intval( $post->ID ); ?></wp:post_id>
  534.         <wp:post_date><?php echo wxr_cdata( $post->post_date ); ?></wp:post_date>
  535.         <wp:post_date_gmt><?php echo wxr_cdata( $post->post_date_gmt ); ?></wp:post_date_gmt>
  536.         <wp:comment_status><?php echo wxr_cdata( $post->comment_status ); ?></wp:comment_status>
  537.         <wp:ping_status><?php echo wxr_cdata( $post->ping_status ); ?></wp:ping_status>
  538.         <wp:post_name><?php echo wxr_cdata( $post->post_name ); ?></wp:post_name>
  539.         <wp:status><?php echo wxr_cdata( $post->post_status ); ?></wp:status>
  540.         <wp:post_parent><?php echo intval( $post->post_parent ); ?></wp:post_parent>
  541.         <wp:menu_order><?php echo intval( $post->menu_order ); ?></wp:menu_order>
  542.         <wp:post_type><?php echo wxr_cdata( $post->post_type ); ?></wp:post_type>
  543.         <wp:post_password><?php echo wxr_cdata( $post->post_password ); ?></wp:post_password>
  544.         <wp:is_sticky><?php echo intval( $is_sticky ); ?></wp:is_sticky>
  545. <?php    if ( $post->post_type == 'attachment' ) : ?>
  546.         <wp:attachment_url><?php echo wxr_cdata( wp_get_attachment_url( $post->ID ) ); ?></wp:attachment_url>
  547. <?php     endif; ?>
  548. <?php     wxr_post_taxonomy(); ?>
  549. <?php    $postmeta = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->postmeta WHERE post_id = %d", $post->ID ) );
  550.         foreach ( $postmeta as $meta ) :
  551.             /**
  552.              * Filters whether to selectively skip post meta used for WXR exports.
  553.              *
  554.              * Returning a truthy value to the filter will skip the current meta
  555.              * object from being exported.
  556.              *
  557.              * @since 3.3.0
  558.              *
  559.              * @param bool   $skip     Whether to skip the current post meta. Default false.
  560.              * @param string $meta_key Current meta key.
  561.              * @param object $meta     Current meta object.
  562.              */
  563.             if ( apply_filters( 'wxr_export_skip_postmeta', false, $meta->meta_key, $meta ) )
  564.                 continue;
  565.         ?>
  566.         <wp:postmeta>
  567.             <wp:meta_key><?php echo wxr_cdata( $meta->meta_key ); ?></wp:meta_key>
  568.             <wp:meta_value><?php echo wxr_cdata( $meta->meta_value ); ?></wp:meta_value>
  569.         </wp:postmeta>
  570. <?php    endforeach;
  571.  
  572.         $_comments = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->comments WHERE comment_post_ID = %d AND comment_approved <> 'spam'", $post->ID ) );
  573.         $comments = array_map( 'get_comment', $_comments );
  574.         foreach ( $comments as $c ) : ?>
  575.         <wp:comment>
  576.             <wp:comment_id><?php echo intval( $c->comment_ID ); ?></wp:comment_id>
  577.             <wp:comment_author><?php echo wxr_cdata( $c->comment_author ); ?></wp:comment_author>
  578.             <wp:comment_author_email><?php echo wxr_cdata( $c->comment_author_email ); ?></wp:comment_author_email>
  579.             <wp:comment_author_url><?php echo esc_url_raw( $c->comment_author_url ); ?></wp:comment_author_url>
  580.             <wp:comment_author_IP><?php echo wxr_cdata( $c->comment_author_IP ); ?></wp:comment_author_IP>
  581.             <wp:comment_date><?php echo wxr_cdata( $c->comment_date ); ?></wp:comment_date>
  582.             <wp:comment_date_gmt><?php echo wxr_cdata( $c->comment_date_gmt ); ?></wp:comment_date_gmt>
  583.             <wp:comment_content><?php echo wxr_cdata( $c->comment_content ) ?></wp:comment_content>
  584.             <wp:comment_approved><?php echo wxr_cdata( $c->comment_approved ); ?></wp:comment_approved>
  585.             <wp:comment_type><?php echo wxr_cdata( $c->comment_type ); ?></wp:comment_type>
  586.             <wp:comment_parent><?php echo intval( $c->comment_parent ); ?></wp:comment_parent>
  587.             <wp:comment_user_id><?php echo intval( $c->user_id ); ?></wp:comment_user_id>
  588. <?php        $c_meta = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->commentmeta WHERE comment_id = %d", $c->comment_ID ) );
  589.             foreach ( $c_meta as $meta ) :
  590.                 /**
  591.                  * Filters whether to selectively skip comment meta used for WXR exports.
  592.                  *
  593.                  * Returning a truthy value to the filter will skip the current meta
  594.                  * object from being exported.
  595.                  *
  596.                  * @since 4.0.0
  597.                  *
  598.                  * @param bool   $skip     Whether to skip the current comment meta. Default false.
  599.                  * @param string $meta_key Current meta key.
  600.                  * @param object $meta     Current meta object.
  601.                  */
  602.                 if ( apply_filters( 'wxr_export_skip_commentmeta', false, $meta->meta_key, $meta ) ) {
  603.                     continue;
  604.                 }
  605.             ?>
  606.             <wp:commentmeta>
  607.                 <wp:meta_key><?php echo wxr_cdata( $meta->meta_key ); ?></wp:meta_key>
  608.                 <wp:meta_value><?php echo wxr_cdata( $meta->meta_value ); ?></wp:meta_value>
  609.             </wp:commentmeta>
  610. <?php        endforeach; ?>
  611.         </wp:comment>
  612. <?php    endforeach; ?>
  613.     </item>
  614. <?php
  615.     }
  616.     }
  617. } ?>
  618. </channel>
  619. </rss>
  620. <?php
  621. }
  622.