- http://www.rocq.net/yann/ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /** * Implementation of hook_help() */ function wordpress_import_help($path, $arg) { $output = ''; switch ($path) { case "admin/help#wordpress_import": $output = '
'. t("This module imports a WXR file generated by Wordpress blog software into Drupal") .'
'; break; } return $output; } /** * Implementation of hook_menu() */ function wordpress_import_menu() { $items = array(); $items['admin/content/wordpress_import'] = array( 'title' => 'Wordpress import', 'description' => t('Import Wordpress WXR file'), 'page callback' => 'wordpress_import_home', 'access callback' => 'user_access', 'access callback' => TRUE, ); return $items; } /** * hook_perm * * @return array perms * @author Yann Rocq **/ function wordpress_import_perm() { return array('import wordpress blog'); } function wordpress_import_home() { return wordpress_import_wizard(); } function wordpress_import_wizard() { $step = arg(3); ctools_include('wizard'); ctools_include('object-cache'); // *** SETUP ARRAY multistep setup **** $form_info = array( 'id' => 'wordpress_import', 'path' => "admin/content/wordpress_import/%step", 'show trail' => FALSE, 'show back' => FALSE, 'show cancel' => TRUE, 'show return' => FALSE, 'next text' => t('Next'), 'next callback' => 'wordpress_import_form_subtask_next', 'finish callback' => 'wordpress_import_form_subtask_finish', 'return callback' => 'wordpress_import_form_subtask_finish', 'cancel callback' => 'wordpress_import_form_subtask_cancel', // this controls order, as well as form labels 'order' => array( 'file' => t('Source file'), 'options' => t('Options'), 'og' => t('Organic groups'), 'mapusers' => t('Map users'), 'newusers' => t('New users'), 'ready' => t('Ready'), ), // here we map a step to a form id. 'forms' => array( 'file' => array( 'form id' => 'wordpress_import_form_file' ), 'options' => array( 'form id' => 'wordpress_import_form_options' ), 'og' => array( 'form id' => 'wordpress_import_form_og' ), 'mapusers' => array( 'form id' => 'wordpress_import_form_mapusers' ), 'newusers' => array( 'form id' => 'wordpress_import_form_newusers' ), 'ready' => array( 'form id' => 'wordpress_import_form_ready' ), ), ); // *** SETTING THE FORM UP FOR MULTISTEP *** // $form_state = array( 'cache name' => NULL, ); $wordpress_import = wordpress_import_form_get_page_cache(NULL); if (!$wordpress_import && $step != '') { drupal_goto('admin/content/wordpress_import'); return; } if (!$wordpress_import) { drupal_set_message($step); $step = current(array_keys($form_info['order'])); $wordpress_import = new stdClass(); ctools_object_cache_set('wordpress_import', $form_state['cache name'], $wordpress_import); } $form_state['wordpress_import_obj'] = $wordpress_import; // Skip OG step if module isn't present, or if in basic mode if ($step == 'og' && (!module_exists('og') || !og_is_group_post_type($wordpress_import->options['nodetype']))) { drupal_goto('admin/content/wordpress_import/mapusers'); } // Skip users creation step if no new users if ($step == 'newusers' && !array_search('newuser',$wordpress_import->usermap)) { drupal_goto('admin/content/wordpress_import/ready'); } $output = ctools_wizard_multistep_form($form_info, $step, $form_state); return $output; } /*---------------- CTools cache handling functions ------------ */ function wordpress_import_form_clear_page_cache($name) { ctools_object_cache_clear('wordpress_import', $name); } function wordpress_import_form_get_page_cache($name) { $cache = ctools_object_cache_get('wordpress_import', $name); return $cache; } /*-------------------------- Form Steps ---------------------- */ function wordpress_import_form_file(&$form, &$form_state) { $wordpress_import = &$form_state['wordpress_import_obj']; $form['informations'] = array( '#value' => t('This module will import a Wordpress eXtended RSS (WXR) file generated by Wordpress. If you need instructions on creating this file, please read the documentation. You must make a backup copy of your Drupal database before proceeding!', array('@codex' => url('http://codex.wordpress.org/Tools_Export_SubPanel'))) ); // Upload file form element $form['upload'] = array( '#type' => 'file', '#title' => t('Upload your WXR file'), '#size' => 40, '#description' => t('The file can\'t exceed %maximum megabytes', array('%maximum' => $base_path . file_upload_max_size()/1024/1024)), ); // Create and scan module directory $wordpress_import_path = file_create_path('wordpress'); file_check_directory($wordpress_import_path, TRUE); $files = file_scan_directory($wordpress_import_path, '.*\.xml'); if (count($files) > 0) { foreach (file_scan_directory($wordpress_import_path, '.*\.xml') as $file) { $options[$file->basename] = $file->basename; } $description = ''; } else { $options = array(); $description = t('No files found in %directory', array('%directory' => file_create_path(file_directory_path() .'/wordpress'))); } // Local file selector element $form['local'] = array( '#title' => t('Or, alternatively, select a local WXR file'), '#type' => 'radios', '#description' => $description, '#options' => $options ); $form['#attributes'] = array('enctype' => "multipart/form-data"); $form_state['no buttons'] = TRUE; } function wordpress_import_form_file_validate(&$form, &$form_state) { if ($form_state['clicked_button']['#wizard type'] == 'cancel') { return; } // Process uploaded file (if any), and set file path $upload = file_save_upload('upload'); if ($upload) { $form_state['values']['upload'] = $upload->filename; $filepath = $upload->filepath; } else { $filepath = file_directory_path().'/wordpress/'.$form_state['values']['local']; } // Make sure a file was uploaded or a local file was selected if (empty($form_state['values']['upload']) && empty($form_state['values']['local'])) { form_set_error('upload',t('You must specify a WXR file to upload or select a local WXR file. If you attempted to upload a file, the operation may have failed.')); return; } else { $form_state['wordpress_import_obj']->filepath = $filepath; } // Load the file, perform basic validation and extract Wordpress users if (wordpress_import_get_entries($form_state['wordpress_import_obj'])) { $wpusers = wordpress_import_get_wpusers($form_state['wordpress_import_obj']->data); $form_state['wordpress_import_obj']->wpusers = $wpusers; $form_state['wordpress_import_obj']->usermap = $wpusers; // Clear usermap values foreach ($form_state['wordpress_import_obj']->usermap as $key => $value) { $form_state['wordpress_import_obj']->usermap[$key] = 0; } // Don't keep the data in cache at this stage (otherwise there's a risk of out-of-memory errors) unset($form_state['wordpress_import_obj']->data); } else { form_set_error('upload',t('The file does not appear to be a valid WXR file.')); } } function wordpress_import_form_file_submit(&$form, &$form_state) { (!empty($form_state['values']['upload'])) ? ($filesource = t('uploaded')) : ($filesource = t('local')); $fileinfo = pathinfo($form_state['wordpress_import_obj']->filepath); drupal_set_message(t('Successfully loaded @filesource file "@filename"', array('@filesource' => $filesource, '@filename' => $fileinfo['basename'])),'success'); } function wordpress_import_form_options(&$form, &$form_state) { $wordpress_import = &$form_state['wordpress_import_obj']; $form['basic_options'] = array( '#type' => 'fieldset', '#title' => t('Options'), '#collapsible' => FALSE, '#tree' => TRUE ); // Post content type $node_types = node_get_types(); $content_types = array('' => ''); foreach ($node_types as $k => $v) { if (!module_exists('og') || (module_exists('og') && !og_is_group_type($k))) { $content_types[$k] = $v->name; } } $form['basic_options']['nodetype'] = array( '#type' => 'select', '#title' => t('Import posts in content type'), '#description' => t('All imported posts will be assigned the selected content type. If you are unsure, select "Story"'), '#default_value' => '', '#options' => $content_types, ); $form['basic_options']['usermap_type'] = array( '#title' => t('User mapping'), '#type' => 'radios', '#description' => t('Single user will import all posts as one specified Drupal user. Manual permits the mapping of an existing or new Drupal user to each Wordpress author.'), '#options' => array( 'default' => t('Single user'), 'manual' => t('Manual')) ); $form['advanced_options'] = array( '#type' => 'fieldset', '#title' => t('Advanced options'), '#collapsible' => TRUE, '#collapsed' => TRUE, '#tree' => TRUE ); $form['advanced_options']['disable_tags'] = array( '#type' => 'checkbox', '#title' => t('Don\'t import categories and tags'), '#default_value' => FALSE, '#disabled' => FALSE, '#description' => t('Check this box to disable import of categories and tags') ); $form['advanced_options']['disable_comments'] = array( '#type' => 'checkbox', '#title' => t('Don\'t import comments'), '#default_value' => FALSE, '#disabled' => FALSE, '#description' => t('Check this box to disable import of comments') ); $form['advanced_options']['disable_trackbacks'] = array( '#type' => 'checkbox', '#title' => t('Don\'t import trackbacks'), '#default_value' => FALSE, '#disabled' => FALSE, '#description' => t('Check this box to disable import of trackbacks') ); $form['advanced_options']['aliases'] = array( '#type' => 'checkbox', '#title' => t('Create path aliases'), '#default_value' => FALSE, '#disabled' => FALSE, '#description' => t('This option tries to preserve the path of the wordpress original posts. It is useful only if the url of your Drupal site root is the same as the Wordpress site (!root) and if Clean URLs are activated', array('!root' => $wordpress_import->data['link'])) ); $form['advanced_options']['images'] = array( '#type' => 'checkbox', '#title' => t('Transfer images'), '#default_value' => FALSE, '#description' => t('Try to download the images referenced in the blog posts locally') ); // Warn if some key modules are not found if (!module_exists('taxonomy')) { drupal_set_message(t('Could not find module "path". Categories and tags will not be imported.'), 'error'); $form['advanced_options']['disable_tags']['#default_value'] = TRUE; $form['advanced_options']['disable_tags']['#disabled'] = TRUE; } if (!module_exists('comment')) { drupal_set_message(t('Could not find module "comment". Comments and tackbacks will not be imported.'), 'error'); $form['advanced_options']['disable_comments']['#default_value'] = TRUE; $form['advanced_options']['disable_comments']['#disabled'] = TRUE; } if (!module_exists('trackback')) { drupal_set_message(t('Could not find module "trackback". Trackbacks will not be imported.'), 'error'); $form['advanced_options']['disable_trackbacks']['#default_value'] = TRUE; $form['advanced_options']['disable_trackbacks']['#disabled'] = TRUE; } if (!module_exists('path')) { drupal_set_message(t('Could not find module "path". Create paths option disabled.'), 'warning'); $form['advanced_options']['aliases']['#default_value'] = FALSE; $form['advanced_options']['aliases']['#disabled'] = TRUE; } } function wordpress_import_form_options_validate(&$form, &$form_state) { if ($form_state['clicked_button']['#wizard type'] == 'cancel') { return; } if (empty($form_state['values']['basic_options']['nodetype'])) { form_set_error('basic_options][nodetype',t('You must specify a content type to import Wordpress posts into.')); } if (empty($form_state['values']['basic_options']['usermap_type'])) { form_set_error('basic_options][usermap_type',t('You must specify a user mapping method.')); } } function wordpress_import_form_options_submit(&$form, &$form_state) { // Clear messages drupal_get_messages(); $options = $form_state['values']['basic_options'] + $form_state['values']['advanced_options']; $form_state['wordpress_import_obj']->options = $options; } function wordpress_import_form_og(&$form, &$form_state) { $wordpress_import = &$form_state['wordpress_import_obj']; $form['informations'] = array( '#value' => t('The content type you selected is an OG group post node type. You may select OG parameters for the imported posts.') ); $form['og_nodeapi'] = array( '#type' => 'fieldset', '#title' => t('Organic groups'), '#collapsible' => FALSE, '#tree' => TRUE, ); og_form_add_og_audience($form, $form_state); if (module_exists('og_access')) { $form['og_nodeapi']['og_public'] = array( '#type' => 'checkbox', '#title' => 'Public', '#description' => t('Show this post to everyone, or only to members of the groups checked above. Posts without any groups are always public.'), ); } } function wordpress_import_form_og_submit(&$form, &$form_state) { $form_state['wordpress_import_obj']->og_groups = $form_state['values']['og_nodeapi']['visible']['og_groups']; $form_state['wordpress_import_obj']->og_public = $form_state['values']['og_nodeapi']['og_public']; } function wordpress_import_form_mapusers(&$form, &$form_state) { $wordpress_import = &$form_state['wordpress_import_obj']; // Get Drupal users $sql = "SELECT * FROM {users} ORDER BY name ASC"; $result = db_query($sql); while ($drupal_user = db_fetch_array($result)) { if (!empty($drupal_user['uid'])) { $drupal_users[$drupal_user['uid']] = $drupal_user['name']; } } if ($wordpress_import->options['usermap_type'] == 'default') { $drupal_users = array('newuser' => t('Create new user')) + $drupal_users; $form['defaultuser'] = array( '#type' => 'select', '#title' => t('Default user'), '#description' => t('Map all Wordpress authors to one single Drupal user.'), '#options' => $drupal_users, ); } else { $drupal_users = array('newuser' => t('Create new user'), 'noimport' => t('Do not import')) + $drupal_users; $form['usermap'] = array( '#title' => t('Users mapping'), '#type' => 'fieldset', '#description' => t('Map each Wordpress user to a distinct Drupal user. The number of posts for each Worpress user is indicated next to the usernames.'), '#collapsible' => FALSE, '#tree' => TRUE ); foreach ($wordpress_import ->usermap as $wp_user => $drupal_user) { $form['usermap'][$wp_user] = array( '#type' => 'select', '#title' => $wp_user . ' (' . $wordpress_import->wpusers[$wp_user] . ')', '#options' => $drupal_users, ); } } } function wordpress_import_form_mapusers_validate(&$form, &$form_state) { if ($form_state['clicked_button']['#wizard type'] == 'cancel') { return; } // Make sure there is something to import if (count($form_state['values']['usermap']) > 0) { $i = FALSE; foreach ($form_state['values']['usermap'] as $wp_user => $drupal_user) { if ($drupal_user != 'noimport') { $i = TRUE; break; } } if (!$i) { form_set_error('usermap', t('Nothing to import!')); } } elseif (empty($form_state['values']['defaultuser'])) { form_set_error('defaultuser', t('Nothing to import!')); } } function wordpress_import_form_mapusers_submit(&$form, &$form_state) { $wordpress_import = &$form_state['wordpress_import_obj']; if ($wordpress_import->options['usermap_type'] == 'default') { foreach ($wordpress_import->usermap as $key => $value) { $wordpress_import->usermap[$key] = $form_state['values']['defaultuser']; } } else { $wordpress_import->usermap = $form_state['values']['usermap']; } } function wordpress_import_form_newusers(&$form, &$form_state) { $wordpress_import = &$form_state['wordpress_import_obj']; $form['newuser'] = array('#tree' => TRUE); if ($wordpress_import->options['usermap_type'] == 'default') { $form['newuser']['default'] = array('#type' => 'fieldset', '#title' => t('All Wordpress authors')); $form['newuser']['default']['name'] = array('#type' => 'textfield', '#title' => t('Username for new user')); $form['newuser']['default']['mail'] = array('#type' => 'textfield', '#title' => t('E-mail address for new user')); } else { foreach ($wordpress_import->usermap as $key => $value) { if ($value == 'newuser') { $form['newuser'][$key] = array('#type' => 'fieldset', '#title' => t('Wordpress author %user', array('%user' => $key))); $form['newuser'][$key]['name'] = array('#type' => 'textfield', '#title' => t('Username for Wordpress author %user', array('%user' => $key)), '#default_value' => $key); $form['newuser'][$key]['mail'] = array('#type' => 'textfield', '#title' => t('E-mail address for Wordpress author %user', array('%user' => $key))); } } } } function wordpress_import_form_newusers_validate(&$form, &$form_state) { if ($form_state['clicked_button']['#wizard type'] == 'cancel') { return; } foreach ($form_state['values']['newuser'] as $key => $value) { // Check usernames if ($error = user_validate_name($value['name'])) { form_set_error('newuser]['. $key .'][name', $error); } elseif (user_load(array('name' => $value['name']))) { form_set_error('newuser]['. $key .'][name', t('User !user already exists.', array('!user' => $value['name']))); } elseif (is_array($user['name']) && in_array(strtolower($value['name']), $user['name'])) { form_set_error('newuser]['. $key .'][name', t('Two users have the same name (!user).', array('!user' => $value['name']))); } // Check user emails if ($error = user_validate_mail($value['mail'])) { form_set_error('newuser]['. $key .'][mail', $error); } elseif (user_load(array('mail' => $value['mail']))) { form_set_error('newuser]['. $key .'][mail', t('User with mail !mail already exists.', array('!mail' => $value['mail']))); } elseif (is_array($user['mail']) && in_array(strtolower($value['mail']), $user['mail'])) { form_set_error('newuser]['. $key .'][mail', t('Two users have the same mail (!mail).', array('!mail' => $value['mail']))); } $user['name'][] = strtolower($value['name']); $user['mail'][] = strtolower($value['mail']); } } function wordpress_import_form_newusers_submit(&$form, &$form_state) { $form_state['wordpress_import_obj']->newuser = $form_state['values']['newuser']; } function wordpress_import_form_ready(&$form, &$form_state) { $wordpress_import = &$form_state['wordpress_import_obj']; $form['informations'] = array( // TODO: present nice summary of import process //'#value' => t('Please review the import parameters and click "Finish" to launch the import process.') '#value' => print_r($wordpress_import, TRUE) ); } /* ---------------- Form callback functions ---------------- */ function wordpress_import_form_subtask_next(&$form_state) { $wordpress_import = &$form_state['wordpress_import_obj']; $cache = ctools_object_cache_set('wordpress_import', $form_state['cache name'], $wordpress_import); } function wordpress_import_form_subtask_cancel(&$form_state) { ctools_object_cache_clear('wordpress_import', $form_state['cache name']); $form_state['redirect'] = 'admin/content/wordpress_import'; drupal_get_messages(); drupal_set_message('Import operation cancelled.'); } function wordpress_import_form_subtask_finish(&$form_state) { $wordpress_import = &$form_state['wordpress_import_obj']; wordpress_import_form_clear_page_cache($form_state['cache name']); // Load data from WXR file wordpress_import_get_entries($wordpress_import); // Prepare batch operations $operations = array(); $operations[] = array('wordpress_import_process_blog',array($wordpress_import)); // Set up batch process $batch = array( 'operations' => $operations, 'finished' => 'wordpress_import_batch_finished', 'title' => t('Wordpress import'), 'init_message' => t('Wordpress import is starting processing'), 'progress_message' => t('Processed @current out of @total.'), 'error_message' => t('Wordpress import has encountered an error.'), ); batch_set($batch); batch_process(); } function wordpress_import_process_blog(&$wordpress_import, &$context) { if (empty($context['sandbox'])) { $context['results']['created_users'] = 0; $context['results']['created_nodes'] = 0; $context['results']['created_terms'] = 0; $context['results']['created_categories'] = 0; $context['results']['downloaded_images'] = array(); $context['results']['error_images'] = array(); $context['results']['created_comments'] = 0; $context['results']['created_trackbacks'] = 0; $context['sandbox']['vocab_done'] = FALSE; $context['sandbox']['users_done'] = FALSE; $context['sandbox']['progress'] = 0; $context['sandbox']['max'] = count($wordpress_import->data['posts']) - 1; } if (!$context['sandbox']['vocab_done'] && !$wordpress_import->options['disable_tags']) { wordpress_import_create_vocabularies(&$wordpress_import, &$context); wordpress_import_process_categories(&$wordpress_import, &$context); $context['sandbox']['vocab_done'] = TRUE; } if (!$context['sandbox']['users_done']) { if ($wordpress_import->options['usermap_type'] == 'default' && !empty($wordpress_import->newuser['default'])) { // Create new default Drupal user and assign uid to each Wordpress author $defaultuser = array('mail' => $wordpress_import->newuser['default']['mail'], 'pass' => user_password(), 'name' => $wordpress_import->newuser['default']['name'], 'status' => 1); $defaultuser = user_save('', $defaultuser); $context['results']['created_users']++; foreach ($wordpress_import->usermap as $key => $value) { $wordpress_import->usermap[$key] = $defaultuser->uid; } } elseif ($wordpress_import->options['usermap_type'] == 'manual') { // Create new Drupal users as required and assign uid to corresponding Wordpress author foreach ($wordpress_import->newuser as $key => $value) { $user = array('mail' => $value['mail'], 'pass' => user_password(), 'name' => $value['name'], 'status' => 1); $user = user_save('', $user); $wordpress_import->usermap[$key] = $user->uid; $context['results']['created_users']++; } } } $limit = 10; while($limit > 0 && $context['sandbox']['progress'] != $context['sandbox']['max']) { wordpress_import_process_post($wordpress_import, $context); $context['sandbox']['progress']++; $limit--; } if ($context['sandbox']['progress'] != $context['sandbox']['max']) { $context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max']; } } function wordpress_import_create_vocabularies(&$wordpress_import, &$context) { $category_vocabulary_info = array( 'name' => t('Wordpress category'), 'hierarchy' => 2, 'multiple' => 1, 'nodes' => array($wordpress_import->options['nodetype'] => $wordpress_import->options['nodetype']) ); $tag_vocabulary_info = array( 'name' => t('Wordpress tag'), 'tags' => 1, 'nodes' => array($wordpress_import->options['nodetype'] => $wordpress_import->options['nodetype']) ); $wordpress_import->categories_vocabulary = wordpress_import_create_vocabulary('category', $category_vocabulary_info); $wordpress_import->tags_vocabulary = wordpress_import_create_vocabulary('tag', $tag_vocabulary_info); } function wordpress_import_process_categories(&$wordpress_import, &$context) { $category_mapping = wordpress_import_get_terms($wordpress_import->categories_vocabulary); // Import categories as taxonomy terms if (is_array($wordpress_import->data['categories'])) { foreach ($wordpress_import->data['categories'] as $key => $value) { $category_name = wordpress_import_get_tag($value, 'wp:cat_name'); $category_parent = wordpress_import_get_tag($value, 'wp:category_parent'); if (!$category_mapping[$category_name]) { $category_term = array( 'name' => $category_name, 'vid' => $wordpress_import->categories_vocabulary ); if (!is_null($category_parent) && !empty($category_parent)) { $category_term['parent'] = $category_mapping[$category_parent]; } taxonomy_save_term($category_term); // Save mapping between Wordpress and Drupal categories $category_mapping[$category_name] = $category_term['tid']; $context['results']['created_terms']++; } } $wordpress_import->categories_map = $category_mapping; } } function wordpress_import_process_post(&$wordpress_import, &$context) { $context['sandbox']['node_modified'] = FALSE; $context['sandbox']['taxonomy_modified'] = FALSE; // Get post content $post_index = $context['sandbox']['progress']; $post = $wordpress_import->data['posts'][$post_index]; // Determine Drupal user uid $wp_user = wordpress_import_get_tag($post, 'dc:creator'); $uid = $wordpress_import->usermap[$wp_user]; // Don't import the post if the user hasn't been selected if ($uid == 'noimport' || !ctype_digit($uid)) { return; } // Post type // TODO: import pages but don't hardcode 'page' content type switch (wordpress_import_get_tag($post, 'wp:post_type')) { case 'page': return; } // Don't publish if marked 'draft' or 'private' switch (wordpress_import_get_tag($post, 'wp:status')) { case 'draft': case 'private': $status = 0; break; default: $status = 1; } // Prepare node content $title = html_entity_decode(wordpress_import_get_tag($post, 'title'), ENT_COMPAT, 'UTF-8'); // Empty titles can confuse the path module if (empty($title)) { $title = t('Untitled'); } $content = wordpress_import_get_tag($post, 'content:encoded'); $content = str_replace('', '', $content); $timestamp = strtotime(wordpress_import_get_tag($post, 'wp:post_date')); // Get or create content format as needed $wordpress_import->format = variable_get('wordpress_import_format_id', 0); if (!$wordpress_import->format) { db_query("INSERT INTO {filter_formats} (name,cache) VALUES ('%s',1)", 'Wordpress format'); $wordpress_import->format = db_result(db_query("SELECT MAX(format) AS format FROM {filter_formats}")); db_query("INSERT INTO {filters} (format, module, delta, weight) VALUES (%d, '%s', %d, %d)", $wordpress_import->format, 'filter', 2, 0); variable_set('wordpress_import_format_id', $wordpress_import->format); } // Create node object $node = array( 'type' => $wordpress_import->options['nodetype'], 'teaser' => node_teaser($content, $format_id), 'uid' => $uid, 'title' => $title, 'body' => $content, 'format' => $wordpress_import->format, 'status' => $status, 'promote' => 0, 'created' => $timestamp, 'changed' => $timestamp, 'comment' => wordpress_import_get_tag($post, 'wp:comment_status')=='open'?COMMENT_NODE_READ_WRITE:COMMENT_NODE_READ_ONLY, // TODO: add a language option ); // Save the node initially $node = (object)$node; node_save($node); // Update the context $context['sandbox']['node'] = & $node; $context['results']['created_nodes']++; $context['message'] = t('Import in progress : @created - @title', array('@created' => format_date($timestamp, 'small'),'@title' => $title)); // Process images for this post if ($wordpress_import->options['images']) { wordpress_import_process_post_images($wordpress_import, $context); } // Process categories and tags for this post if (module_exists('taxonomy') && !$wordpress_import->options['disable_tags']) { wordpress_import_process_post_tags($wordpress_import, $context); } // Process comments and trackbacks for this post if (module_exists('comment') && !$wordpress_import->options['disable_comments']) { wordpress_import_process_post_comments($wordpress_import, $context); } // Process link for this post if (module_exists('path') && $wordpress_import->options['aliases']) { wordpress_import_process_post_link($wordpress_import, $context); } // Save any changes if ($context['sandbox']['node_modified']) { node_save($node); } if ($context['sandbox']['taxonomy_modified']) { taxonomy_node_save($node, $drupal_categories); } if (module_exists('og') && og_is_group_post_type($wordpress_import->options['nodetype'])) { $node->og_groups = $wordpress_import->og_groups; $node->og_public = (int) $wordpress_import->og_public; og_save_ancestry($node); } unset($context['sandbox']['node']); } function wordpress_import_process_post_link(&$wordpress_import, &$context) { $link = wordpress_import_get_tag($wordpress_import->data['post'], 'link'); $link = substr($link, strlen($wordpress_import->data['link'])); $link = rtrim($link, '/'); path_set_alias('node/'. $context['sandbox']['node']->nid, $link); } function wordpress_import_process_post_images(&$wordpress_import, &$context) { $node = & $context['sandbox']['node']; $modified = FALSE; // Prepare receiving directory $imgpath = file_create_path('images'); file_check_directory($imgpath, TRUE); // Find image URL in content preg_match_all('/(img|src)=("|\')[^"\'>]+/i', $node->body, $media); $imgdata = preg_replace('/(img|src)("|\'|="|=\')(.*)/i',"$3",$media[0]); foreach($imgdata as $imgurl) { $urlinfo = parse_url($imgurl); $imginfo = pathinfo($urlinfo['path']); if (($urlinfo['scheme'] == 'http' || $urlinfo['scheme'] == 'https') && isset($imginfo['extension'])) { if ((strcasecmp($imginfo['extension'],'jpg') == 0) || (strcasecmp($imginfo['extension'],'jpeg') == 0) || (strcasecmp($imginfo['extension'],'gif') == 0) || (strcasecmp($imginfo['extension'],'png') == 0)) { $ch = curl_init($imgurl); // Check if cURL object OK if (!$ch) { $context['results']['error_images'][] = array('nid' => $context['sandbox']['node']->nid, 'title' => $context['sandbox']['node']->title, 'oldurl' => $imgurl); continue; } // Check if image was already downloaded foreach ($context['results']['downloaded_images'] as $img) { if ($img['imgurl'] == $imgurl) { $content = str_replace($imgurl, $img['newurl'], $node->body); $context['sandbox']['node_modified'] = TRUE; continue 2; } } curl_setopt($ch, CURLOPT_TIMEOUT, 10); // Obtain new URL in case of redirections $imgnewurl = curl_redir_url($ch); curl_close($ch); if ($imgnewurl) { // Download image $imgfile = file_create_filename(urldecode($imginfo['basename']), $imgpath); $imgout = fopen($imgfile, 'wb'); $ch = curl_init($imgnewurl); curl_setopt($ch, CURLOPT_HEADER, false); curl_setopt($ch, CURLOPT_TIMEOUT, 10); curl_setopt($ch, CURLOPT_FILE, $imgout); curl_exec($ch); curl_close($ch); fclose($imgout); $newurl = $imgpath.'/'.$imginfo['basename']; // Replace image URL with new path in post $content = str_replace($imgurl, $newurl, $node->body); $context['sandbox']['node_modified'] = TRUE; $context['results']['downloaded_images'][] = array('nid' => $node->nid, 'oldurl' => $imgurl, 'newurl' => $newurl, 'file' => $imgfile); } else { $context['results']['error_images'][] = array('nid' => $node->nid, 'title' => $node->title, 'oldurl' => $imgurl); } } } } } function wordpress_import_process_post_tags(&$wordpress_import, &$context) { $node = & $context['sandbox']['node']; // Get post content $post_index = $context['sandbox']['progress']; $post = $wordpress_import->data['posts'][$post_index]; // Parse categories preg_match_all('|