285 lines
11 KiB
PHP
285 lines
11 KiB
PHP
<?php
|
|
# Copyright (c) 2003-2005, Jannis Hermanns (on behalf the Serendipity Developer Team)
|
|
# Copyright (c) 2009, Matthew Weigel
|
|
# All rights reserved. See LICENSE file for licensing details
|
|
|
|
require_once S9Y_PEAR_PATH . 'Onyx/RSS.php';
|
|
|
|
class Serendipity_Import_LiveJournalXML extends Serendipity_Import {
|
|
var $info = array('software' => 'LiveJournal XML');
|
|
var $data = array();
|
|
var $inputFields = array();
|
|
var $force_recode = false;
|
|
|
|
function __construct($data) {
|
|
global $serendipity;
|
|
$this->data = $data;
|
|
$this->inputFields = array(array('text' => 'LiveJournal XML',
|
|
'type' => 'input',
|
|
'name' => 'url',
|
|
'default' => $serendipity['serendipityPath'] . $serendipity['uploadPath'] . 'EVbackup.xml'),
|
|
|
|
array('text' => RSS_IMPORT_CATEGORY,
|
|
'type' => 'list',
|
|
'name' => 'category',
|
|
'value' => 0,
|
|
'default' => $this->_getCategoryList()),
|
|
|
|
array('text' => IMPORT_STATUS,
|
|
'type' => 'list',
|
|
'name' => 'type',
|
|
'value' => 'publish',
|
|
'default' => array('publish' => PUBLISH, 'draft' => DRAFT)),
|
|
|
|
array('text' => USERNAME,
|
|
'type' => 'input',
|
|
'name' => 'user',
|
|
'default' => ''),
|
|
|
|
);
|
|
}
|
|
|
|
function _getCategoryList() {
|
|
$res = serendipity_fetchCategories('all');
|
|
$ret = array(0 => NO_CATEGORY);
|
|
if (is_array($res)) {
|
|
foreach ($res as $v) {
|
|
$ret[$v['categoryid']] = $v['category_name'];
|
|
}
|
|
}
|
|
return $ret;
|
|
}
|
|
|
|
function GetChildren(&$vals, &$i) {
|
|
$children = array();
|
|
$cnt = sizeof($vals);
|
|
while (++$i < $cnt) {
|
|
// compare type
|
|
switch ($vals[$i]['type']) {
|
|
case 'cdata':
|
|
$children[] = $vals[$i]['value'];
|
|
break;
|
|
|
|
case 'complete':
|
|
$children[] = array(
|
|
'tag' => $vals[$i]['tag'],
|
|
'attributes' => $vals[$i]['attributes'],
|
|
'value' => $vals[$i]['value']
|
|
);
|
|
break;
|
|
|
|
case 'open':
|
|
$children[] = array(
|
|
'tag' => $vals[$i]['tag'],
|
|
'attributes' => $vals[$i]['attributes'],
|
|
'value' => $vals[$i]['value'],
|
|
'children' => $this->GetChildren($vals, $i)
|
|
);
|
|
break;
|
|
|
|
case 'close':
|
|
return $children;
|
|
}
|
|
}
|
|
}
|
|
|
|
function &parseXML(&$xml) {
|
|
// XML functions
|
|
$xml_string = '<?xml version="1.0" encoding="UTF-8" ?>';
|
|
if (preg_match('@(<\?xml.+\?>)@imsU', $xml, $xml_head)) {
|
|
$xml_string = $xml_head[1];
|
|
}
|
|
|
|
$encoding = 'UTF-8';
|
|
if (preg_match('@encoding="([^"]+)"@', $xml_string, $xml_encoding)) {
|
|
$encoding = $xml_encoding[1];
|
|
}
|
|
|
|
preg_match_all("@(<entry[a-z =\'0-9]*>.*</entry>)@imsU", $xml, $xml_matches);
|
|
if (!is_array($xml_matches)) {
|
|
return false;
|
|
}
|
|
|
|
$i = 0;
|
|
$tree = array();
|
|
$tree[$i] = array(
|
|
'tag' => 'entries',
|
|
'attributes' => '',
|
|
'value' => '',
|
|
'children' => array()
|
|
);
|
|
|
|
foreach($xml_matches[0] as $xml_index => $xml_package) {
|
|
$i = 0;
|
|
|
|
switch(strtolower($encoding)) {
|
|
case 'iso-8859-1':
|
|
case 'utf-8':
|
|
$p = xml_parser_create($encoding);
|
|
break;
|
|
|
|
default:
|
|
$p = xml_parser_create('');
|
|
}
|
|
|
|
xml_parser_set_option($p, XML_OPTION_CASE_FOLDING, 0);
|
|
@xml_parser_set_option($p, XML_OPTION_TARGET_ENCODING, 'UTF-8');
|
|
$xml_package = $xml_string . "\n" . $xml_package;
|
|
xml_parse_into_struct($p, $xml_package, $vals);
|
|
xml_parser_free($p);
|
|
$tree[0]['children'][] = array(
|
|
'tag' => $vals[$i]['tag'],
|
|
'attributes' => $vals[$i]['attributes'],
|
|
'value' => $vals[$i]['value'],
|
|
'children' => $this->GetChildren($vals, $i)
|
|
);
|
|
unset($vals);
|
|
}
|
|
|
|
return $tree;
|
|
}
|
|
|
|
function validateData() {
|
|
return sizeof($this->data);
|
|
}
|
|
|
|
function getInputFields() {
|
|
return $this->inputFields;
|
|
}
|
|
|
|
function getTimestamp($string) {
|
|
if (preg_match('@(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})@', $string, $match)) {
|
|
return mktime($match[4], $match[5], $match[6], $match[2], $match[3], $match[1]);
|
|
} else {
|
|
return time();
|
|
}
|
|
}
|
|
|
|
function gatherComments($entrydata) {
|
|
$comments = array();
|
|
if (is_array($entrydata['children'])) {
|
|
foreach($entrydata['children'] AS $idx3 => $commententry) {
|
|
if ($commententry['tag'] == 'comment' && is_array($commententry['children'])) {
|
|
$comment = array(
|
|
'ip' => '127.0.0.1',
|
|
'status' => 'approved',
|
|
'name' => $commententry['attributes']['poster'] ? $commententry['attributes']['poster'] : 'Anonymous',
|
|
'url' => $commententry['attributes']['poster'] ? "http://" . $commententry['attributes']['poster'] . ".livejournal.com/" : '',
|
|
'email' => '',
|
|
'jtalkid' => $commententry['attributes']['jtalkid'],
|
|
'jparentid' => $commententry['attributes']['parentid'] ? $commententry['attributes']['parentid'] : 0
|
|
);
|
|
if ($comment['name'] == $this->data['user']) {
|
|
if (!empty($serendipity['realname'])) {
|
|
$comment['name'] = $serendipity['realname'];
|
|
} else {
|
|
$comment['name'] = $serendipity['user'];
|
|
}
|
|
$comment['url'] = $serendipity['baseURL'];
|
|
}
|
|
foreach($commententry['children'] AS $idx4 => $commentdata) {
|
|
switch($commentdata['tag']) {
|
|
case 'subject':
|
|
$comment['title'] = $commentdata['value'];
|
|
break;
|
|
case 'body':
|
|
$comment['comment'] = $commentdata['value'];
|
|
break;
|
|
case 'date':
|
|
$comment['time'] = $this->getTimestamp($commentdata['value']);
|
|
break;
|
|
}
|
|
}
|
|
array_push($comments, $comment);
|
|
}
|
|
}
|
|
}
|
|
return $comments;
|
|
}
|
|
|
|
function import() {
|
|
global $serendipity;
|
|
|
|
if (!file_exists($this->data['url'])) {
|
|
printf(FILE_NOT_FOUND, serendipity_specialchars($this->data['url']));
|
|
return false;
|
|
}
|
|
|
|
$file = file_get_contents($this->data['url']);
|
|
$tree =& $this->parseXML($file);
|
|
$serendipity['noautodiscovery'] = 1;
|
|
|
|
foreach($tree[0]['children'] AS $idx => $entry) {
|
|
if (!is_array($entry)) continue;
|
|
if ($entry['tag'] != 'entry') {
|
|
continue;
|
|
}
|
|
|
|
$new_entry = array(
|
|
'allow_comments' => true,
|
|
'extended' => '',
|
|
'categories' => array(),
|
|
'isdraft' => ($this->data['type'] == 'draft' ? 'true' : 'false'),
|
|
'categories' => array($this->data['category'] => $this->data['category'])
|
|
);
|
|
|
|
if (!is_array($entry['children'])) continue;
|
|
|
|
foreach($entry['children'] AS $idx2 => $entrydata) {
|
|
if (!is_array($entrydata)) {
|
|
continue;
|
|
}
|
|
|
|
switch($entrydata['tag']) {
|
|
case 'eventtime':
|
|
$new_entry['timestamp'] = $this->getTimestamp($entrydata['value']);
|
|
break;
|
|
|
|
case 'date':
|
|
$new_entry['timestamp'] = $this->getTimestamp($entrydata['value']);
|
|
break;
|
|
|
|
case 'subject':
|
|
$new_entry['title'] = $entrydata['value'];
|
|
break;
|
|
|
|
case 'event':
|
|
$new_entry['body'] = $entrydata['value'];
|
|
break;
|
|
case 'comments':
|
|
$new_entry['comments'] = $this->gatherComments($entrydata);
|
|
break;
|
|
}
|
|
}
|
|
$id = serendipity_updertEntry($new_entry);
|
|
echo '<span class="msg_notice">Inserted entry #' . $id . ', "' . serendipity_specialchars($new_entry['title']) . '"</span>';
|
|
if (is_array($new_entry['comments'])) {
|
|
$cid_map = array();
|
|
$jids = array();
|
|
foreach($new_entry['comments'] AS $comment) {
|
|
array_push($jids, $comment['jtalkid']);
|
|
if (array_key_exists($comment['jparentid'], $cid_map)) {
|
|
$comment['parent_id'] = $cid_map[$comment['jparentid']];
|
|
}
|
|
$cid = serendipity_insertComment($id, $comment);
|
|
$cid_map[$comment['jtalkid']] = $cid;
|
|
}
|
|
echo '<span class="msg_notice">Inserted comments for entry #' . $id . '</span>';
|
|
}
|
|
|
|
if (function_exists('ob_flush')) {
|
|
@ob_flush();
|
|
}
|
|
if (function_exists('flush')) {
|
|
@flush();
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return 'Serendipity_Import_LiveJournalXML';
|
|
|
|
/* vim: set sts=4 ts=4 expandtab : */
|