Skip to content

Instantly share code, notes, and snippets.

@petenelson
Created January 22, 2013 22:23
Show Gist options
  • Save petenelson/4599174 to your computer and use it in GitHub Desktop.
Save petenelson/4599174 to your computer and use it in GitHub Desktop.
WordPress: GGA Joomla Content Importer - Imports articles from a Joomla database as WordPress posts
<?php
/*
Plugin Name: GGA Joomla Content Importer
Description: Imports articles from Joomla 1.5x into WordPress
Author: <a href="https://twitter.com/GunGeekATX" target="_blank">@GunGeekATX</a>
Version: 1.1
*/
class ggaJoomlaArticleImporter
{
/*
* This plugin was written to handle importing articles from a specific section in Joomla 1.5 into WordPress, specifically
* for a Joomla 1.5 site that had several years of press releases. It's only designed to get articles in one section from Joomla and
* assign one category in WordPress. It's a good starting base if you need to import multiple articles from a Joomla 1.5 database.
*/
// Data for your Joomla DB
var $joomla_db;
var $joomla_host = 'localhost';
var $joomla_username = 'your_username_here';
var $joomla_password = 'your_password_here';
var $joomla_dbname = 'joomla_db_name';
var $joomla_tbl_prefix = 'jos_';
var $joomla_section_id = 3;
// Data for your WordPress install
var $wp_target_category_slug = 'press-announcements';
var $wp_cleanup_category_slug = 'press-announcements-cleanup';
var $wp_post_author_id = 2;
var $actionPrefix = 'ggaJoomlaArticleImporter';
var $version = '1.0';
function __construct()
{
add_action( 'init', array(&$this, 'init'));
add_action( 'admin_menu', array(&$this, 'admin_menu'));
add_action( 'ggaJoomlaArticleImporter_run_cron_import_job', array(&$this, 'run_import_content_job'), 10, 1 );
}
function __destruct() {
if ($this->joomla_db)
mysql_close($this->joomla_db);
}
public function init() {
add_action('wp_ajax_' . $this->actionPrefix . '_create_import_content_job', array(&$this, 'create_import_content_job'));
add_action('wp_ajax_' . $this->actionPrefix . '_check_import_status', array(&$this, 'check_import_status'));
}
public function admin_menu() {
add_menu_page( 'GGA Joomla Importer', 'Joomla Importer', 'import', 'gga-joomla-importer', array(&$this, 'admin_page'));
}
function connect_to_joomla_db() {
$this->joomla_db = @mysql_connect($this->joomla_host, $this->joomla_username, $this->joomla_password);
if (!$this->joomla_db)
return new WP_Error('joomla_connect', 'Unable to connect to db');
if (false === @mysql_select_db($this->joomla_dbname, $this->joomla_db))
return new WP_Error('joomla_select_db', 'Unable to select db');
}
public function admin_page()
{
?>
<div class="wrap">
<h2>Joomla to WordPress Importer</h2>
<p>
This plugin will import articles from from your Joomla 1.5 database into this WordPress site as posts.
</p>
<p>
<table>
<tr>
<td colspan="2">
<h3>Source</h3>
</td>
</tr>
<tr>
<td>
Joomla User@Host:
</td>
<td>
<?php echo htmlspecialchars($this->joomla_username) ?>@<?php echo htmlspecialchars($this->joomla_host) ?>
</td>
</tr>
<tr>
<td>
Joomla Database
</td>
<td>
<?php echo htmlspecialchars($this->joomla_dbname) ?>
</td>
</tr>
<tr>
<td>
Joomla Table Prefix:
</td>
<td>
<?php echo htmlspecialchars($this->joomla_tbl_prefix) ?>
</td>
</tr>
<tr>
<td>
Joomla Section Id:
</td>
<td>
<?php echo htmlspecialchars($this->joomla_section_id) ?>
</td>
</tr>
<tr>
<td colspan="2">
<h3>Target</h3>
</td>
</tr>
<tr>
<td>WordPress Category Slug:</td>
<td>
<?php echo htmlspecialchars($this->wp_target_category_slug) ?>
</td>
</tr>
<tr>
<td>WordPress Category Slug (cleanup):</td>
<td>
<?php echo htmlspecialchars($this->wp_cleanup_category_slug) ?>
</td>
</tr>
<tr>
<td>WordPress Post Author Id:</td>
<td>
<?php echo htmlspecialchars($this->wp_post_author_id) ?>
</td>
</tr>
</table>
</p>
<input type="button" id="ggaStartImport" value="Start Import" class="button button-primary" />
<br/>
<div id="ggaImportMessageWrapper" style="display: none ">
<h3>Import progress</h3>
<div class="ggaImportMessage">
</div>
</div>
<script type="text/javascript">
jQuery(document).ready(function() {
jQuery('#ggaStartImport').click(function() {
jQuery(this).attr('disabled', 'disabled').val('Running Import...');
jQuery('#ggaImportMessageWrapper').show();
ggaSetImportMessage('Starting Import...<br/>')
jQuery.post(ajaxurl, { 'action':'<?php echo $this->actionPrefix ?>_create_import_content_job' }, function(response) {
if (response.errors) {
if (response.errors.joomla_connect)
ggaSetImportMessage('Error: Unable to connect to Joomla SQL host');
if (response.errors.joomla_select_db)
ggaSetImportMessage('Error: Unable to select to Joomla DB');
if (response.errors.joomla_query)
ggaSetImportMessage('Error: Unable to query Joomla content table');
} else {
ggaAppendImportMessage('Transient job id ' + response.job_id + '<br/>');
setTimeout(ggaCheckImportStatus, 1000, response.job_id);
}
}, 'json');
});
});
function ggaSetImportMessage(message) {
jQuery('.ggaImportMessage').html(message);
}
function ggaAppendImportMessage(message) {
jQuery('.ggaImportMessage').append(message);
}
function ggaCheckImportStatus(jobid) {
jQuery.post(ajaxurl, { 'action':'<?php echo $this->actionPrefix ?>_check_import_status', 'job_id':jobid }, function(response) {
ggaSetImportMessage('Imported ' + response.total_imported + '/' + response.total_to_import );
if (response.total_imported < response.total_to_import )
setTimeout(ggaCheckImportStatus, 1000, jobid);
else
jQuery('#ggaStartImport').val('Import completed');
}, 'json');
}
</script>
</div>
<?php
}
public function create_import_content_job() {
$id = '_gji_' . uniqid(); // short for _gga_joomla_import_
$trans = new stdClass();
$trans->job_id = $id;
$trans->results = array();
$ids = $this->get_content_ids_to_import();
if (is_wp_error( $ids ))
$trans->errors = $ids->errors;
else {
$trans->content_ids = $ids;
set_transient( $id, $trans, 60*60*24 );
// create a one-time cron job to run the import
wp_schedule_single_event(time(), 'ggaJoomlaArticleImporter_run_cron_import_job', array($id));
}
echo json_encode($trans);
die();
}
public function run_import_content_job($transient_id) {
$trans = get_transient( $transient_id );
$response = new stdClass();
$response->job_id = '';
if ($trans && $trans->content_ids && is_array($trans->content_ids)) {
$response->job_id = $trans->job_id;
for ($i=0; $i < count($trans->content_ids); $i++)
$this->import_content_id($trans->content_ids[$i], $trans->job_id);
}
echo json_encode($response);
die();
}
function check_import_status() {
$trans = get_transient( $_REQUEST['job_id'] );
$results = new stdClass();
$results->job_id = '';
if ($trans) {
$results->job_id = $trans->job_id;
$results->total_to_import = count($trans->content_ids);
$results->total_imported = 0;
for ($i=0; $i < count($trans->results); $i++)
$results->total_imported += ( is_wp_error($trans->results[$i]->wp_post_error) || $trans->results[$i]->wp_post_id > 0) ? 1 : 0;
}
echo json_encode($results);
die();
}
function get_content_ids_to_import() {
$err = null;
if (!$this->joomla_db)
$err = $this->connect_to_joomla_db();
if (is_wp_error( $err ))
return $err;
$content_ids = array();
$result = @mysql_query(
sprintf('SELECT `%scontent`.`id` FROM `%scontent` WHERE `%scontent`.`sectionid` = %d and state = 1',
$this->joomla_tbl_prefix, $this->joomla_tbl_prefix, $this->joomla_tbl_prefix, $this->joomla_section_id
),
$this->joomla_db);
if (!$result)
return new WP_Error('joomla_query', 'Unable to query db');
$rows = mysql_num_rows($result);
for ($i=0; $i < $rows; $i++)
$content_ids[] = mysql_result($result, $i, 'id') or die(mysql_error());
return $content_ids;
}
function import_content_id($id, $transient_id) {
if (!$this->joomla_db)
$this->connect_to_joomla_db();
$trans = get_transient( $transient_id);
$results = new stdClass();
$results->wp_post_id = 0;
$results->wp_post_error = null;
$results->id = $content_ids[$i];
$results->title = '';
$results->existed = false;
$cat = get_category_by_slug( $this->wp_target_category_slug );
$content_ids = array();
$result = mysql_query(sprintf("SELECT `id`, `title`, `alias`, `fulltext`, `publish_up`, `alias` FROM `%scontent` WHERE `%scontent`.`id` = %d",
$this->joomla_tbl_prefix, $this->joomla_tbl_prefix, $id
), $this->joomla_db) or die(mysql_error());
$rows = mysql_num_rows($result);
if ($rows > 0) {
$alias = mysql_result($result, 0, 'alias');
$title = $this->word_cleanup(mysql_result($result, 0, 'title'));
$fulltext = $this->word_cleanup(mysql_result($result, 0, 'fulltext'));
$results = new stdClass();
$results->id = mysql_result($result, 0, 'id');
$results->title = $title;
$slug = wp_unique_post_slug(
sanitize_title_with_dashes($results->id . '-' . $alias),
0,
'publish',
'post',
0);
$post_data = array(
'post_title' => $title,
'post_content' => $fulltext,
'post_status' => 'publish',
'post_name' => $slug,
'post_date' => mysql_result($result, 0, 'publish_up'),
'comment_status' => 'closed',
'ping_status' => 'closed',
'post_type' => 'post',
'post_author' => $this->wp_post_author_id
);
// query by post_meta to see if this has already been imported
$query = new WP_Query( array( 'meta_key' => '_gga_joomla_content_id', 'meta_value' => $results->id ) );
if ($query->have_posts() ) {
$query->the_post();
$results->existed = true;
$results->existing_id = get_the_id();
$results->wp_post_id = $results->existing_id;
wp_update_post( $post_data );
}
else
{
$insert_results = wp_insert_post( $post_data, true );
if (is_wp_error( $insert_results ) ) {
$results->wp_post_error = $insert_results;
}
else {
$results->wp_post_id = $insert_results;
// flag this with the content ID from Joomla
update_post_meta( $results->wp_post_id, '_gga_joomla_content_id', $results->id );
// flag that this was converted using this plugin, just in case you need to query for it later
update_post_meta( $results->wp_post_id, '_gga_imported_from_joomla', true );
}
}
wp_set_post_categories($results->wp_post_id, array($cat->cat_ID));
// check the post content to see if anything needs cleanup, like img tags, links to index.php, etc
if ($this->post_needs_cleanup($fulltext))
wp_set_post_categories($results->wp_post_id, array($cat->cat_ID, $cat_cleanup->cat_ID)); // need to pass all categories, this is an overwrite function
wp_reset_query();
wp_reset_postdata();
}
$trans->results[] = $results;
set_transient( $transient_id, $trans, 60*60*24 );
}
function post_needs_cleanup($content) {
// images linked to images/stories, etc
// linkes to the default index.php file in Joomla vs permalinks
return
false !== stripos($content, '<img') ||
false !== stripos($content, 'index.php')
;
}
function word_cleanup ($str)
{
// this cleans up some stuff copy/pasted from MS Word
$str = mb_convert_encoding($str, 'HTML-ENTITIES', 'UTF-8');
$str = str_replace('&#2013266080;', ' ', $str); // space
$str = str_replace('&#2013266094;', '®', $str); // reg trademark
$str = str_replace('&#2013266073;', '™', $str); // non-reg trademark
$str = str_replace('&#2013266070;', '-', $str);
$str = str_replace('&#2013266067;', '"', $str);
$str = str_replace('&#2013266068;', '"', $str);
$str = str_replace('&#2013266065;', "'", $str);
$str = str_replace('&#2013266066;', "'", $str);
return $str;
}
}
new ggaJoomlaArticleImporter();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment