Update of /cvsroot/php-blog/serendipity/include/admin/importers
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27345/include/admin/importers
Added Files:
Tag: branch-smarty
generic.inc.php movabletype.inc.php wordpress.inc.php
Log Message:
- Draft for new import framework. It's working, but might need some changes to make it a little more pretty
Note: Please review your importer methods, like validateData() etc.
- Split importer and exporter up into two menuitems
- Don't let serendipity_guessInput() parse data, it should just act on the data given
- Add 'file' type to serendipity_guessInput(), implementing <input type="file">
--- NEW FILE: generic.inc.php ---
<?php # $Id: generic.inc.php,v 1.1.2.1 2004/11/15 21:06:49 tomsommer Exp $
require_once 'bundled-libs/Onyx/RSS.php';
@define('STATUS', 'Status after import');
@define('RSS_IMPORT_DESC', 'The RSS import will fetch an RSS feed and insert all the entries contained there inside your article base. You can choose if you want to import the items in DRAFT or PUBLISHED state. Categories in the foreign feed need to contain the exact same name like you entered the names in Serendipity. Via the other input box you can choose the category you want to have entries associated which do not match the imported feed.');
@define('RSS_IMPORT_CATEGORY', 'Use this default category for entries without a matching category');
class Serendipity_Import_Generic extends Serendipity_Import {
var $info = array('software' => 'Generic RSS import');
var $data = array();
var $inputFields = array();
function Serendipity_Import_Generic($data) {
$this->data = $data;
$this->inputFields = array(array('text' => (RSS .' '. URL),
'type' => 'input',
'name' => 'url'),
array('text' => STATUS,
'type' => 'list',
'name' => 'type',
'value' => 'publish',
'default' => array('draft' => DRAFT,
'publish' => PUBLISH)),
array('text' => RSS_IMPORT_CATEGORY,
'type' => 'list',
'name' => 'category',
'value' => 0,
'default' => $this->_fuckCategoryList()),
array('text' => RSS_IMPORT_BODYONLY,
'type' => 'bool',
'name' => 'bodyonly',
'value' => 'false'));
}
function validateData() {
return sizeof($this->data);
}
function getInputFields() {
return $this->inputFields;
}
function _fuckCategoryList() {
$res = serendipity_fetchCategories('all');
$ret = array(0 => NO_CATEGORY);
foreach ( $res as $v ) {
$ret[$v['categoryid']] = $v['category_name'];
}
return $ret;
}
function buildEntry($item, &$entry) {
global $serendipity;
$entry = array();
$bodyonly = serendipity_get_bool($this->data['bodyonly']);
$bodyonly = false;
if ($item['description']) {
$entry['body'] = utf8_decode($item['description']);
}
if ($item['content:encoded']) {
if (!isset($entry['body']) || $bodyonly) {
$data = &$entry['body'];
} else {
$data = &$entry['extended'];
}
// See if the 'description' element is a substring of the 'content:encoded' part. If it is,
// we will only fetch the full 'content:encoded' part. If it's not a substring, we append
// the 'content:encoded' part to either body or extended entry (respecting the 'bodyonly'
// switch). We substract 4 letters because of possible '...' additions to an entry.
$testbody = substr(trim(strip_tags($entry['body'])), 0, -4);
if ($testbody != substr(trim(strip_tags($item['content:encoded'])), 0, strlen($testbody))) {
$data .= utf8_decode($item['content:encoded']);
} else {
$data = utf8_decode($item['content:encoded']);
}
}
$entry['title'] = utf8_decode($item['title']);
$entry['timestamp'] = utf8_decode(strtotime(isset($item['pubdate']) ? $item['pubdate'] : $item['dc:date']));
if ($entry['timestamp'] == -1) {
$entry['timestamp'] = time();
}
if ($serendipity['POST']['type'] == 'draft') {
$entry['isdraft'] = 'true';
} else {
$entry['isdraft'] = 'false';
}
if (!empty($item['category'])) {
$cat = serendipity_fetchCategoryInfo(0, trim(utf8_decode($item['category'])));
if (is_array($cat) && isset($cat['categoryid'])) {
$entry['categories'][] = $cat['categoryid'];
}
}
if (!is_array($entry['categories'])) {
$entry['categories'][] = $this->data['category'];
}
if (!isset($entry['extended'])) {
$entry['extended'] = '';
}
$entry['allow_comments'] = true;
return true;
}
function import() {
global $serendipity;
$c = &new Onyx_RSS();
$c->parse($this->data['url']);
$serendipity['noautodiscovery'] = 1;
while ($item = $c->getNextItem()) {
if ($this->buildEntry($item, $entry)) {
serendipity_updertEntry($entry);
}
}
return true;
}
}
return 'Serendipity_Import_Generic';
/* vim: set sts=4 ts=4 expandtab : */
?>
--- NEW FILE: wordpress.inc.php ---
<?php # $Id: wordpress.inc.php,v 1.1.2.1 2004/11/15 21:06:49 tomsommer Exp $
/*****************************************************************
* WordPress Importer, by Even *
*****************************************************************/
@define('WORDPRESS_DATA', 'WordPress data');
@define('CREATE_AUTHOR', 'Create author \'%s\'.');
@define('CREATE_CATEGORY', 'Create category \'%s\'.');
@define('MYSQL_REQUIRED', 'You must have the MySQL extension in order to perform this action.');
@define('COULDNT_CONNECT', 'Could not connect to MySQL database: %s.');
@define('COULDNT_SELECT_DB', 'Could not select database: %s.');
@define('COULDNT_SELECT_USER_INFO', 'Could not select user information: %s.');
@define('COULDNT_SELECT_CATEGORY_INFO', 'Could not select category information: %s.');
@define('COULDNT_SELECT_ENTRY_INFO', 'Could not select entry information: %s.');
@define('COULDNT_SELECT_COMMENT_INFO', 'Could not select comment information: %s.');
class Serendipity_Import_WordPress extends Serendipity_Import {
var $info = array('software' => 'WordPress');
var $data = array();
var $inputFields = array();
function Serendipity_Import_WordPress($data) {
$this->data = $data;
$this->inputFields = array(array('text' => INSTALL_DBHOST,
'type' => 'input',
'name' => 'host'),
array('text' => INSTALL_DBUSER,
'type' => 'input',
'name' => 'user'),
array('text' => INSTALL_DBPASS,
'type' => 'protected',
'name' => 'pass'),
array('text' => INSTALL_DBNAME,
'type' => 'input',
'name' => 'name'),
array('text' => INSTALL_DBPREFIX,
'type' => 'input',
'name' => 'prefix'));
}
function validateData() {
return sizeof($this->data);
}
function getInputFields() {
return $this->inputFields;
}
function import() {
global $serendipity;
$this->data['prefix'] = serendipity_db_escape_string($this->data['prefix']);
$users = array();
$categories = array();
$entries = array();
if ( !extension_loaded('mysql') ) {
return MYSQL_REQUIRED;;
}
$wpdb = @mysql_connect($this->data['host'], $this->data['user'], $this->data['pass']);
if ( !$wpdb ) {
return sprintf(COULDNT_CONNECT, $this->data['host']);
}
if ( !@mysql_select_db($this->data['name']) ) {
return sprintf(COULDNT_SELECT_DB, mysql_error($wpdb));
}
/* Users */
$res = @mysql_query("SELECT ID, user_login, user_pass, user_email, user_level FROM {$this->data['prefix']}users;", $wpdb);
if ( !$res ) {
return sprintf(COULDNT_COULDNT_SELECT_USER_INFO, mysql_error($wpdb));
}
for ( $x=0 ; $x<mysql_num_rows($res) ; $x++ ) {
$users[$x] = mysql_fetch_assoc($res);
$data = array('right_publish' => ($users[$x]['user_level'] >= 1) ? 1 : 0,
'username' => $users[$x]['user_login'],
'password' => $users[$x]['user_pass']); // WP uses md5, too.
if ( $users[$x]['user_level'] <= 1 ) {
$data['userlevel'] = USERLEVEL_EDITOR;
} elseif ( $users[$x]['user_level'] < 5 ) {
$data['userlevel'] = USERLEVEL_CHIEF;
} else {
$data['userlevel'] = USERLEVEL_ADMIN;
}
serendipity_db_insert('authors', $data);
$users[$x]['authorid'] = serendipity_db_insert_id('authors', 'authorid');
}
/* Categories */
$res = @mysql_query("SELECT cat_ID, cat_name, category_description, category_parent FROM {$this->data['prefix']}categories ORDER BY category_parent, cat_ID;", $wpdb);
if ( !$res ) {
return sprintf(COULDNT_SELECT_CATEGORY_INFO, mysql_error($wpdb));
}
// Get all the info we need
for ( $x=0 ; $x<mysql_num_rows($res) ; $x++ )
$categories[] = mysql_fetch_assoc($res);
// Insert all categories as top level (we need to know everyone's ID before we can represent the hierarchy).
for ( $x=0 ; $x<sizeof($categories) ; $x++ ) {
$cat = array('category_name' => $categories[$x]['cat_name'],
'category_description' => $categories[$x]['category_description'],
'parentid' => 0, // <---
'category_left' => 0,
'category_right' => 0);
serendipity_db_insert('category', $cat);
$categories[$x]['categoryid'] = serendipity_db_insert_id('category', 'categoryid');
}
// There has to be a more efficient way of doing this...
foreach ( $categories as $cat ) {
if ( $cat['category_parent'] != 0 ) {
// Find the parent
$par_id = 0;
foreach ( $categories as $possible_par ) {
if ( $possible_par['cat_ID'] == $cat['category_parent'] ) {
$par_id = $possible_par['categoryid'];
break;
}
}
if ( $par_id != 0 ) {
serendipity_db_query("UPDATE {$serendipity['dbPrefix']}category SET parentid={$par_id} WHERE categoryid={$cat['categoryid']};");
} // else { echo "D'oh! " . random_string_of_profanity(); }
}
}
serendipity_rebuildCategoryTree();
/* Entries */
$res = @mysql_query("SELECT * FROM {$this->data['prefix']}posts ORDER BY post_date;", $wpdb);
if ( !$res ) {
return sprintf(COULDNT_SELECT_ENTRY_INFO, mysql_error($wpdb));
}
for ( $x=0 ; $x<mysql_num_rows($res) ; $x++ ) {
$entries[$x] = mysql_fetch_assoc($res);
$entry = array('title' => $entries[$x]['post_title'],
'isdraft' => ($entries[$x]['post_status'] == 'publish') ? 'false' : 'true',
'allow_comments' => ($entries[$x]['comment_status '] == 'open ') ? 'true' : 'false',
'timestamp' => strtotime($entries[$x]['post_date']),
'body' => $entries[$x]['post_content']);
foreach ( $users as $user ) {
if ( $user['ID'] == $entries[$x]['post_author'] ) {
$entry['authorid'] = $user['authorid'];
break;
}
}
if ( !is_int($entries[$x]['entryid'] = serendipity_updertEntry($entry)) ) {
return $entries[$x]['entryid'];
}
}
/* Entry/category */
$res = @mysql_query("SELECT * FROM {$this->data['prefix']}post2cat;", $wpdb);
if ( !$res ) {
return sprintf(COULDNT_SELECT_ENTRY_INFO, mysql_error($wpdb));
}
while ( $a = mysql_fetch_assoc($res) ) {
foreach ( $categories as $category ) {
if ( $category['cat_ID'] == $a['category_id'] ) {
foreach ( $entries as $entry ) {
if ( $a['post_id'] == $entry['ID'] ) {
$data = array('entryid' => $entry['entryid'],
'categoryid' => $category['categoryid']);
serendipity_db_insert('entrycat', $data);
break;
}
}
break;
}
}
}
/* Comments */
$res = @mysql_query("SELECT * FROM {$this->data['prefix']}comments;", $wpdb);
if ( !$res ) {
return sprintf(COULDNT_SELECT_COMMENT_INFO, mysql_error($wpdb));
}
while ( $a = mysql_fetch_assoc($res) ) {
foreach ( $entries as $entry ) {
if ( $entry['ID'] == $a['comment_post_ID'] ) {
$comment = array('entry_id ' => $entry['entryid'],
'parent_id' => 0,
'timestamp' => strtotime($a['comment_date']),
'author' => $a['comment_author'],
'email' => $a['comment_author_email'],
'url' => $a['comment_author_url'],
'ip' => $a['comment_author_IP'],
'status' => 'approved',
'body' => $a['comment_content'],
'type' => 'NORMAL');
serendipity_db_insert('comments', $comment);
serendipity_approveComment($cid, $id, true);
}
}
}
// That was fun.
return true;
}
}
return 'Serendipity_Import_WordPress';
/* vim: set sts=4 ts=4 expandtab : */
?>
--- NEW FILE: movabletype.inc.php ---
<?php # $Id: movabletype.inc.php,v 1.1.2.1 2004/11/15 21:06:49 tomsommer Exp $
/*****************************************************************
* MovableType Importer, by Even *
*****************************************************************/
@define('MAX_COMPAT_OLD_BLOG', 'To enable maximum compatibility with your old blog, please...');
@define('MT_DATA_FILE', 'Movable Type data file');
@define('FORCE', 'Force');
class Serendipity_Import_MovableType extends Serendipity_Import {
var $info = array('software' => 'MovableType');
var $data = array();
var $inputFields = array();
function Serendipity_Import_MovableType($data) {
$this->data = $data;
$this->inputFields = array(array('text' => MT_DATA_FILE,
'type' => 'file',
'name' => 'mt_dat'),
array('text' => FORCE,
'type' => 'bool',
'name' => 'mt_force',
'default' => 'true'));
}
function validateData() {
return sizeof($this->data);
}
function getInputFields() {
return $this->inputFields;
}
function import() {
global $serendipity;
$force = ($this->data['force'] == 'true');
$contents = file_get_contents($serendipity['FILES']['tmp_name']['mt_dat']);
$authors = array();
$categories = serendipity_fetchCategories();
$tasks = array();
$entries = array();
$n = 0;
foreach ( preg_split('/\r?\n--------\r?\n/', $contents) as $entry ) {
if ( preg_match_all('/([A-Z ]+):( |\r?\n)(.*)\r?\n(-----)?/', $entry, $res) ) {
$entries[$n]['categories'] = array();
for ( $x=0 ; $x<sizeof($res[1]) ; $x++ ) {
switch ( $res[1][$x] ) {
case 'AUTHOR':
if ( !isset($authors[$res[3][$x]]) ) {
$au_inf = serendipity_fetchAuthor($res[3][$x]);
if ( !is_array($au_inf) ) {
$tasks[] = sprintf(CREATE_AUTHOR, htmlspecialchars($res[3][$x]));
$au_inf = serendipity_fetchAuthor($serendipity['authorid']);
}
$authors[$res[3][$x]] = $au_inf[0];
}
$entries[$n]['authorid'] = $authors[$res[3][$x]]['authorid'];
$entries[$n]['author'] = $authors[$res[3][$x]]['username'];
break;
case 'TITLE':
$entries[$n]['title'] = $res[3][$x];
break;
case 'STATUS':
$entries[$n]['isdraft'] = ($res[3][$x] == 'Publish') ? 'false' : 'true';
break;
case 'ALLOW COMMENTS':
$entries[$n]['allow_comments'] = ($res[3][$x] == '1') ? 'true' : 'false';
break;
case 'DATE':
$entries[$n]['timestamp'] = strtotime($res[3][$x]);
if ( $entries[$n]['timestamp'] == 0 ) {
$entries[$n]['timestamp'] = time();
}
break;
case 'BODY':
$entries[$n]['body'] = $res[3][$x];
break;
case 'EXTENDED BODY':
$entries[$n]['extended'] = $res[3][$x];
break;
case 'PRIMARY CATEGORY':
case 'CATEGORY':
$cat_found = false;
if ( is_array($categories) ) {
for ( $y=0 ; $y<sizeof($categories) ; $y++ ) {
if ( $categories[$y]['category_name'] == $res[3][$x] ) {
$cat_found = true;
break;
}
}
}
if ( $cat_found && !in_array($categories[$y]['categoryid'], $entries[$n]['categories']) ) {
$entries[$n]['categories'][] = $categories[$y]['categoryid'];
$entries[$n]['categories'][] = $categories[$y]['categoryid'];
}
else {
$tasks[] = sprintf(CREATE_CATEGORY, htmlspecialchars($res[3][$x]));
}
break;
}
}
}
$n++;
}
if ( !sizeof($tasks) || $force == true ) {
foreach ( $entries as $entry ) {
if ( !is_int($r = serendipity_updertEntry($entry)) ) {
echo '<div class="important">' . $r . '</div>';
}
}
return true;
}
else {
return array_unique($tasks);
}
}
}
return 'Serendipity_Import_MovableType';
?>
|