WordPress.org

Make WordPress Core

Changeset 6390


Ignore:
Timestamp:
12/16/2007 09:34:48 PM (11 years ago)
Author:
ryan
Message:

Import file attachments. Props tellyworth. fixes #5466

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/wp-admin/import/wordpress.php

    r6376 r6390  
    1111    var $allauthornames = array ();
    1212    var $j = -1;
    13     var $another_pass = false;
     13    var $fetch_attachments = false;
     14    var $url_remap = array ();
    1415
    1516    function header() {
     
    190191            echo '</li>';
    191192        }
    192 
     193?> 
     194</ol>   
     195<h2><?php _e('Import Attachments'); ?></h2>
     196<p>
     197    <input type="checkbox" value="1" name="attachments" id="import-attachments" />
     198    <label for="import-attachments"><?php _e('Download and import file attachments') ?></label>
     199</p>
     200
     201<?php
    193202        echo '<input type="submit" value="Submit">'.'<br />';
    194203        echo '</form>';
    195         echo '</ol>';
    196204
    197205    }
     
    296304        $post_content = str_replace('<br>', '<br />', $post_content);
    297305        $post_content = str_replace('<hr>', '<hr />', $post_content);
    298 
     306       
    299307        preg_match_all('|<category domain="tag">(.*?)</category>|is', $post, $tags);
    300308        $tags = $tags[1];
     
    334342
    335343            echo '<li>';
    336             printf(__('Importing post <i>%s</i>...'), stripslashes($post_title));
    337344
    338345            $post_author = $this->checkauthor($post_author); //just so that if a post already exists, new users are not created by checkauthor
    339346
    340347            $postdata = compact('post_author', 'post_date', 'post_date_gmt', 'post_content', 'post_title', 'post_excerpt', 'post_status', 'post_name', 'comment_status', 'ping_status', 'post_modified', 'post_modified_gmt', 'guid', 'post_parent', 'menu_order', 'post_type');
    341             $comment_post_ID = $post_id = wp_insert_post($postdata);
     348            if ($post_type == 'attachment') {
     349                $remote_url = $this->get_tag( $post, 'wp:attachment_url' );
     350                if ( !$remote_url )
     351                    $remote_url = $guid;
     352                   
     353                $comment_post_ID = $post_id = $this->process_attachment($postdata, $remote_url);
     354                if ( !$post_id or is_wp_error($post_id) )
     355                    return $post_id;
     356            }
     357            else {
     358                printf(__('Importing post <i>%s</i>...'), stripslashes($post_title));
     359                $comment_post_ID = $post_id = wp_insert_post($postdata);
     360            }
     361           
    342362            if ( is_wp_error( $post_id ) )
    343363                return $post_id;
     
    421441            add_post_meta( $post_id, $key, $value );
    422442        } }
     443       
     444        print "</li>\n";
     445    }
     446   
     447    function process_attachment($postdata, $remote_url) {
     448        if ($this->fetch_attachments and $remote_url) {
     449            printf( __('Importing attachment <i>%s</i>... '), htmlspecialchars($remote_url) );
     450            $upload = $this->fetch_remote_file($postdata, $remote_url);
     451            if ( is_wp_error($upload) ) {
     452                printf( __('Remote file error: %s'), htmlspecialchars($upload->get_error_message()) );
     453                return $upload;
     454            }
     455            else {
     456                print '('.size_format(filesize($upload['file'])).')';
     457            }
     458               
     459            $postdata['guid'] = $upload['url'];
     460
     461            // as per wp-admin/includes/upload.php
     462            $post_id = wp_insert_attachment($postdata, $upload['file']);
     463            wp_update_attachment_metadata( $post_id, wp_generate_attachment_metadata( $post_id, $upload['file'] ) );
     464            return $post_id;
     465        }
     466        else {
     467            printf( __('Skipping attachment <i>%s</i>'), htmlspecialchars($remote_url) );
     468        }
     469    }
     470   
     471    function fetch_remote_file($post, $url) {
     472        $upload = wp_upload_dir($post['post_date']);
     473       
     474        // extract the file name and extension from the url
     475        $file_name = basename($url);
     476
     477        // get placeholder file in the upload dir with a unique sanitized filename
     478        $upload = wp_upload_bits( $file_name, 0, '', $post['post_date']);
     479        if ( $upload['error'] ) {
     480            echo $upload['error'];
     481            return new WP_Error( 'upload_dir_error', $upload['error'] );
     482        }
     483       
     484        // fetch the remote url and write it to the placeholder file
     485        $headers = wp_get_http($url, $upload['file']);
     486       
     487        // make sure the fetch was successful
     488        if ( $headers['response'] != '200' )
     489            return new WP_Error( 'import_file_error', __(sprintf('Remote file returned error response %d', intval($headers['response']))) );
     490        elseif ( isset($headers['content-length']) && filesize($upload['file']) != $headers['content-length'] )
     491            return new WP_Error( 'import_file_error', __('Remote file is incorrect size') );
     492           
     493        // keep track of the old and new urls so we can substitute them later
     494        $this->url_remap[$url] = $upload['url'];
     495        // if the remote url is redirected somewhere else, keep track of the destination too
     496        if ( $headers['x-final-location'] != $url )
     497            $this->url_remap[$headers['x-final-location']] = $upload['url'];
     498       
     499        return $upload;
     500       
     501    }
     502   
     503    // update url references in post bodies to point to the new local files
     504    function backfill_attachment_urls() {
     505       
     506        // make sure we do the longest urls first, in case one is a substring of another
     507        function cmpr_strlen($a, $b) {
     508            return strlen($b) - strlen($a);
     509        }
     510        uksort($this->url_remap, 'cmpr_strlen');
     511               
     512        global $wpdb;
     513        foreach ($this->url_remap as $from_url => $to_url) {
     514            $wpdb->query( $wpdb->prepare("UPDATE {$wpdb->posts} SET post_content = REPLACE(post_content, '%s', '%s')", $from_url, $to_url) );
     515        }
    423516    }
    424517   
     
    436529    }
    437530
    438     function import($id) {
     531    function import($id, $fetch_attachments = false) {
    439532        $this->id = (int) $id;
     533        $this->fetch_attachments = (bool) $fetch_attachments;
    440534
    441535        $file = get_attached_file($this->id);
     
    453547        $result = $this->process_posts();
    454548        $this->backfill_parents();
     549        $this->backfill_attachment_urls();
    455550        wp_defer_term_counting(false);
    456551        if ( is_wp_error( $result ) )
     
    488583            case 2:
    489584                check_admin_referer('import-wordpress');
    490                 $result = $this->import( $_GET['id'] );
     585                $result = $this->import( $_GET['id'], $_POST['attachments'] );
    491586                if ( is_wp_error( $result ) )
    492587                    echo $result->get_error_message();
  • trunk/wp-admin/includes/file.php

    r6116 r6390  
    148148        return $upload_error_handler( $file, $uploads['error'] );
    149149
    150     // Increment the file number until we have a unique file to save in $dir. Use $override['unique_filename_callback'] if supplied.
    151     if ( isset( $unique_filename_callback ) && function_exists( $unique_filename_callback ) ) {
    152         $filename = $unique_filename_callback( $uploads['path'], $file['name'] );
    153     } else {
    154         $number = '';
    155         $filename = str_replace( '#', '_', $file['name'] );
    156         $filename = str_replace( array( '\\', "'" ), '', $filename );
    157         if ( empty( $ext) )
    158             $ext = '';
    159         else
    160             $ext = ".$ext";
    161         while ( file_exists( $uploads['path'] . "/$filename" ) ) {
    162             if ( '' == "$number$ext" )
    163                 $filename = $filename . ++$number . $ext;
    164             else
    165                 $filename = str_replace( "$number$ext", ++$number . $ext, $filename );
    166         }
    167         $filename = str_replace( $ext, '', $filename );
    168         $filename = sanitize_title_with_dashes( $filename ) . $ext;
    169     }
     150    $filename = wp_unique_filename( $uploads['path'], $file['name'], $ext, $unique_filename_callback );
    170151
    171152    // Move the file to the uploads dir
  • trunk/wp-includes/functions.php

    r6367 r6390  
    532532}
    533533
    534 
    535 function wp_get_http_headers( $url, $red = 1 ) {
     534// perform a HTTP HEAD or GET request
     535// if $file_path is a writable filename, this will do a GET request and write the file to that path
     536// returns a list of HTTP headers
     537function wp_get_http( $url, $file_path = false, $red = 1 ) {
    536538    global $wp_version;
    537539    @set_time_limit( 60 );
     
    546548        $parts['port'] = 80;
    547549
    548     $head = "HEAD $file HTTP/1.1\r\nHOST: $host\r\nUser-Agent: WordPress/" . $wp_version . "\r\n\r\n";
     550    if ( $file_path )
     551        $request_type = 'GET';
     552    else
     553        $request_type = 'HEAD';
     554       
     555    $head = "$request_type $file HTTP/1.1\r\nHOST: $host\r\nUser-Agent: WordPress/" . $wp_version . "\r\n\r\n";
    549556
    550557    $fp = @fsockopen( $host, $parts['port'], $err_num, $err_msg, 3 );
     
    556563    while ( !feof( $fp ) && strpos( $response, "\r\n\r\n" ) == false )
    557564        $response .= fgets( $fp, 2048 );
    558     fclose( $fp );
    559565    preg_match_all( '/(.*?): (.*)\r/', $response, $matches );
    560566    $count = count( $matches[1] );
     
    568574
    569575        $code = $headers['response'];
    570         if ( ( '302' == $code || '301' == $code ) && isset( $headers['location'] ) )
    571                 return wp_get_http_headers( $headers['location'], ++$red );
    572 
     576        if ( ( '302' == $code || '301' == $code ) && isset( $headers['location'] ) ) {
     577                fclose($fp);
     578                return wp_get_http_headers( $headers['location'], $get, ++$red );
     579        }
     580   
     581    // make a note of the final location, so the caller can tell if we were redirected or not
     582    $headers['x-final-location'] = $url;
     583
     584    // HEAD request only
     585    if ( !$file_path ) {
     586        fclose($fp);
     587        return $headers;
     588    }
     589   
     590    // GET request - fetch and write it to the supplied filename
     591    $content_length = $headers['content-length'];
     592    $got_bytes = 0;
     593    $out_fp = fopen($file_path, 'w');
     594    while ( !feof($fp) ) {
     595        $buf = fread( $fp, 4096 );
     596        fwrite( $out_fp, $buf );
     597        $got_bytes += strlen($buf);
     598        // don't read past the content-length
     599        if ($content_length and $got_bytes >= $content_length)
     600            break;
     601    }
     602   
     603    fclose($out_fp);
     604    fclose($fp);
    573605    return $headers;
     606}
     607
     608function wp_get_http_headers( $url ) {
     609    return wp_get_http( $url, false );
    574610}
    575611
     
    9931029
    9941030// Returns an array containing the current upload directory's path and url, or an error message.
    995 function wp_upload_dir() {
     1031function wp_upload_dir( $time = NULL ) {
    9961032    $siteurl = get_option( 'siteurl' );
    9971033    //prepend ABSPATH to $dir and $siteurl to $url if they're not already there
     
    10101046    if ( get_option( 'uploads_use_yearmonth_folders' ) ) {
    10111047        // Generate the yearly and monthly dirs
    1012         $time = current_time( 'mysql' );
     1048        if ( !$time )
     1049            $time = current_time( 'mysql' );
    10131050        $y = substr( $time, 0, 4 );
    10141051        $m = substr( $time, 5, 2 );
     
    10271064}
    10281065
    1029 function wp_upload_bits( $name, $deprecated, $bits ) {
     1066// return a filename that is sanitized and unique for the given directory
     1067function wp_unique_filename( $dir, $name, $ext, $unique_filename_callback = NULL ) {
     1068   
     1069    // Increment the file number until we have a unique file to save in $dir. Use $override['unique_filename_callback'] if supplied.
     1070    if ( $unique_filename_callback && function_exists( $unique_filename_callback ) ) {
     1071        $filename = $unique_filename_callback( $dir, $name );
     1072    } else {
     1073        $number = '';
     1074        $filename = str_replace( '#', '_', $name );
     1075        $filename = str_replace( array( '\\', "'" ), '', $filename );
     1076        if ( empty( $ext) )
     1077            $ext = '';
     1078        else
     1079            $ext = ".$ext";
     1080        $filename = $filename . $ext;
     1081        while ( file_exists( $dir . "/$filename" ) ) {
     1082            if ( '' == "$number$ext" )
     1083                $filename = $filename . ++$number . $ext;
     1084            else
     1085                $filename = str_replace( "$number$ext", ++$number . $ext, $filename );
     1086        }
     1087        $filename = str_replace( $ext, '', $filename );
     1088        $filename = sanitize_title_with_dashes( $filename ) . $ext;
     1089    }
     1090   
     1091    return $filename;
     1092}
     1093
     1094function wp_upload_bits( $name, $deprecated, $bits, $time = NULL ) {
    10301095    if ( empty( $name ) )
    10311096        return array( 'error' => __( "Empty filename" ) );
     
    10351100        return array( 'error' => __( "Invalid file type" ) );
    10361101
    1037     $upload = wp_upload_dir();
     1102    $upload = wp_upload_dir( $time );
    10381103
    10391104    if ( $upload['error'] !== false )
    10401105        return $upload;
    10411106
    1042     $number = '';
    10431107    $filename = $name;
    10441108    $path_parts = pathinfo( $filename );
    10451109    $ext = $path_parts['extension'];
    1046     if ( empty( $ext ) )
    1047         $ext = '';
    1048     else
    1049         $ext = ".$ext";
    1050     while ( file_exists( $upload['path'] . "/$filename" ) ) {
    1051         if ( '' == "$number$ext" )
    1052             $filename = $filename . ++$number . $ext;
    1053         else
    1054             $filename = str_replace( "$number$ext", ++$number . $ext, $filename );
    1055     }
     1110   
     1111    $filename = wp_unique_filename( $upload['path'], $path_parts['basename'], $ext );
    10561112
    10571113    $new_file = $upload['path'] . "/$filename";
Note: See TracChangeset for help on using the changeset viewer.