Make WordPress Core


Ignore:
Timestamp:
11/15/2007 05:36:43 AM (16 years ago)
Author:
ryan
Message:

Don't load entire wxr import file at once to conserve memory. Props tellyworth. fixes #5357

File:
1 edited

Legend:

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

    r6332 r6336  
    44
    55    var $posts = array ();
    6     var $posts_processed = array ();
     6    var $post_ids_processed = array ();
    77    // Array of arrays. [[0] => XML fragment, [1] => New post ID]
    88    var $file;
     
    1010    var $mtnames = array ();
    1111    var $newauthornames = array ();
     12    var $allauthornames = array ();
    1213    var $j = -1;
     14    var $another_pass = false;
    1315
    1416    function header() {
     
    8486    }
    8587
    86     function get_entries() {
     88    function get_entries($process_post_func=NULL) {
    8789        set_magic_quotes_runtime(0);
    8890
    89         $this->posts = array();
    90         $this->categories = array();
    91         $this->tags = array();
    92         $num = 0;
    93         $doing_entry = false;
    94 
    95         $fp = fopen($this->file, 'r');
    96         if ($fp) {
    97             while ( !feof($fp) ) {
    98                 $importline = rtrim(fgets($fp));
    99 
    100                 if ( false !== strpos($importline, '<wp:category>') ) {
    101                     preg_match('|<wp:category>(.*?)</wp:category>|is', $importline, $category);
    102                     $this->categories[] = $category[1];
    103                     continue;
    104                 }
    105                 if ( false !== strpos($importline, '<wp:tag>') ) {
    106                     preg_match('|<wp:tag>(.*?)</wp:tag>|is', $importline, $tag);
    107                     $this->tags[] = $tag[1];
    108                     continue;
    109                 }
    110                 if ( false !== strpos($importline, '<item>') ) {
    111                     $this->posts[$num] = '';
    112                     $doing_entry = true;
    113                     continue;
    114                 }
    115                 if ( false !== strpos($importline, '</item>') ) {
    116                     $num++;
    117                     $doing_entry = false;
    118                     continue;
    119                 }
    120                 if ( $doing_entry ) {
    121                     $this->posts[$num] .= $importline . "\n";
    122                 }
    123             }
    124 
    125             foreach ($this->posts as $post) {
    126                 $post_ID = (int) $this->get_tag( $post, 'wp:post_id' );
    127                 if ($post_ID) {
    128                     $this->posts_processed[$post_ID][0] = &$post;
    129                     $this->posts_processed[$post_ID][1] = 0;
    130                 }
    131             }
    132 
    133             fclose($fp);
    134         }
    135     }
    136 
     91#       $this->posts = array();
     92#       $this->categories = array();
     93#       $this->tags = array();
     94#       $num = 0;
     95
     96        for ($i=0; $i<2; $i++) {
     97            $this->another_pass = false;
     98            $doing_entry = false;
     99   
     100            $fp = fopen($this->file, 'r');
     101            if ($fp) {
     102                while ( !feof($fp) ) {
     103                    $importline = rtrim(fgets($fp));
     104   
     105                    if ( false !== strpos($importline, '<wp:category>') ) {
     106                        preg_match('|<wp:category>(.*?)</wp:category>|is', $importline, $category);
     107                        $this->categories[] = $category[1];
     108                        continue;
     109                    }
     110                    if ( false !== strpos($importline, '<wp:tag>') ) {
     111                        preg_match('|<wp:tag>(.*?)</wp:tag>|is', $importline, $tag);
     112                        $this->tags[] = $tag[1];
     113                        continue;
     114                    }
     115                    if ( false !== strpos($importline, '<item>') ) {
     116                        $this->post = '';
     117                        $doing_entry = true;
     118                        continue;
     119                    }
     120                    if ( false !== strpos($importline, '</item>') ) {
     121                        $num++;
     122                        $doing_entry = false;
     123                        if ($process_post_func)
     124                            call_user_func($process_post_func, $this->post);
     125                        continue;
     126                    }
     127                    if ( $doing_entry ) {
     128                        $this->post .= $importline . "\n";
     129                    }
     130                }
     131   
     132                fclose($fp);
     133            }
     134           
     135            // skip the second loop iteration unless it's needed
     136            if ( !$this->another_pass )
     137                break;
     138        }
     139
     140    }
     141   
    137142    function get_wp_authors() {
    138         $temp = array ();
    139         $i = -1;
    140         foreach ($this->posts as $post) {
    141             if ('' != trim($post)) {
    142                 ++ $i;
    143                 $author = $this->get_tag( $post, 'dc:creator' );
    144                 array_push($temp, "$author"); //store the extracted author names in a temporary array
    145             }
    146         }
     143        $this->get_entries(array(&$this, 'process_author'));
    147144
    148145        // We need to find unique values of author names, while preserving the order, so this function emulates the unique_value(); php function, without the sorting.
     146        $temp = $this->allauthornames;
    149147        $authors[0] = array_shift($temp);
    150148        $y = count($temp) + 1;
     
    182180            }
    183181        }
     182       
    184183    }
    185184
     
    211210
    212211    function select_authors() {
    213         $file = wp_import_handle_upload();
    214         if ( isset($file['error']) ) {
    215             echo '<p>'.__('Sorry, there has been an error.').'</p>';
    216             echo '<p><strong>' . $file['error'] . '</strong></p>';
    217             return;
    218         }
    219         $this->file = $file['file'];
    220         $this->id = (int) $file['id'];
    221 
    222         $this->get_entries();
     212        $this->get_entries(array(&$this, 'process_author'));
    223213        $this->wp_authors_form();
    224214    }
     
    274264    }
    275265
     266    function process_author($post) {
     267        $author = $this->get_tag( $post, 'dc:creator' );
     268        if ($author)
     269            $this->allauthornames[] = $author;
     270    }
     271
    276272    function process_posts() {
     273        return; //FIXME
    277274        $i = -1;
    278275        echo '<ol>';
    279276
    280         foreach ($this->posts as $post) {
    281             $result = $this->process_post($post);
    282             if ( is_wp_error( $result ) )
    283                 return $result;
    284         }
     277        $this->get_entries(array(&$this, 'process_post'));
    285278
    286279        echo '</ol>';
     
    293286    function process_post($post) {
    294287        global $wpdb;
    295 
     288       
    296289        $post_ID = (int) $this->get_tag( $post, 'wp:post_id' );
    297         if ( $post_ID && !empty($this->posts_processed[$post_ID][1]) ) // Processed already
     290        if ( $post_ID && !empty($this->post_ids_processed[$post_ID]) ) // Processed already
    298291            return 0;
    299292
     
    342335            // If it has parent, process parent first.
    343336            $post_parent = (int) $post_parent;
    344             if ($parent = $this->posts_processed[$post_parent]) {
    345                 if (!$parent[1]) {
    346                     $result = $this->process_post($parent[0]); // If not yet, process the parent first.
    347                     if ( is_wp_error( $result ) )
    348                         return $result;
    349                 }
    350                 $post_parent = $parent[1]; // New ID of the parent;
     337            if ($post_parent) {
     338                if ( $parent = $this->post_ids_processed[$post_parent] ) {
     339                    $post_parent = $parent;  // new ID of the parent
     340                }
     341                else {
     342                    // wait until the parent has been processed
     343                    $this->another_pass = true;
     344                    return;
     345                }
    351346            }
    352347
     
    362357
    363358            // Memorize old and new ID.
    364             if ( $post_id && $post_ID && $this->posts_processed[$post_ID] )
    365                 $this->posts_processed[$post_ID][1] = $post_id; // New ID.
     359            if ( $post_id && $post_ID ) {
     360                $this->post_ids_processed[intval($post_ID)] = intval($post_id);
     361            }
    366362
    367363            // Add categories.
     
    440436    }
    441437
    442     function import() {
    443         $this->id = (int) $_GET['id'];
     438    function import($id) {
     439        $this->id = (int) $id;
    444440
    445441        $this->file = get_attached_file($this->id);
    446442        $this->get_authors_from_post();
    447         $this->get_entries();
     443        $this->get_entries(array(&$this, 'process_post'));
    448444        $this->process_categories();
    449445        $this->process_tags();
     
    451447        if ( is_wp_error( $result ) )
    452448            return $result;
     449    }
     450   
     451    function handle_upload() {
     452        $file = wp_import_handle_upload();
     453        if ( isset($file['error']) ) {
     454            echo '<p>'.__('Sorry, there has been an error.').'</p>';
     455            echo '<p><strong>' . $file['error'] . '</strong></p>';
     456            return false;
     457        }
     458        $this->file = $file['file'];
     459        $this->id = (int) $file['id'];
     460        return true;
    453461    }
    454462
     
    466474            case 1 :
    467475                check_admin_referer('import-upload');
    468                 $this->select_authors();
     476                if ( $this->handle_upload() )
     477                    $this->select_authors();
    469478                break;
    470479            case 2:
    471480                check_admin_referer('import-wordpress');
    472                 $result = $this->import();
     481                $result = $this->import( $_GET['id'] );
    473482                if ( is_wp_error( $result ) )
    474483                    echo $result->get_error_message();
Note: See TracChangeset for help on using the changeset viewer.