Файл: textpattern-4.5.7/rpc/TXP_RPCServer.php
Строк: 912
<?php
/*
XML-RPC Server for Textpattern 4.0.x
http://txp.kusor.com/rpc-api
(C)2005-2006 The Textpattern Development Team - http://textpattern.com
@author Pedro Palazón - http://kusor.com
$HeadURL: https://textpattern.googlecode.com/svn/releases/4.5.7/source/rpc/TXP_RPCServer.php $
$LastChangedRevision: 4011 $
*/
if (!defined('txpath')) die('txpath is undefined.');
require_once txpath.'/lib/txplib_html.php';
class TXP_RPCServer extends IXR_IntrospectionServer
{
function TXP_RPCServer()
{
global $enable_xmlrpc_server;
$this->IXR_IntrospectionServer();
// Add API Methods as callbacks:
if ($enable_xmlrpc_server)
{
// Blogger API [http://www.blogger.com/developers/api/] - add as server capability
$this->capabilities['bloggerAPI'] = array(
'specUrl' => 'http://www.blogger.com/developers/api/',
'specVersion' => 2
);
$this->addCallback(
'blogger.newPost',
'this:blogger_newPost',
array('int', 'string', 'string', 'string', 'string', 'string', 'boolean'),
'makes a new post to a designated blog'
);
$this->addCallback(
'blogger.editPost',
'this:blogger_editPost',
array('boolean', 'string', 'string', 'string', 'string', 'string', 'boolean'),
'changes the contents of a given post'
);
$this->addCallback(
'blogger.getUsersBlogs',
'this:blogger_getUsersBlogs',
array('struct', 'string', 'string', 'string'),
'return information about all the blogs a given user is member of'
);
$this->addCallback(
'blogger.getUserInfo',
'this:blogger_getUserInfo',
array('struct', 'string', 'string', 'string'),
'return information about the current user'
);
$this->addCallback(
'blogger.getTemplate',
'this:blogger_getTemplate',
array('string', 'string', 'string', 'string', 'string', 'string'),
'return section template - main will return default template, archiveIndex will return section template'
);
$this->addCallback(
'blogger.setTemplate',
'this:blogger_setTemplate',
array('boolean', 'string', 'string', 'string', 'string', 'string', 'string'),
'updates section template - main=default template, archiveIndex=section template'
);
// non-official Blogger API methods - supported by XML-RPC clients as BloggerAPI2
// Place all this info on a public URI
$this->addCallback(
'blogger.getPost',
'this:blogger_getPost',
array('struct', 'string', 'string', 'string', 'string'),
'retrieves contents for the given postid'
);
$this->addCallback(
'blogger.deletePost',
'this:blogger_deletePost',
array('boolean', 'string', 'string', 'string', 'string', 'boolean'),
'deletes a given post'
);
$this->addCallback(
'blogger.getRecentPosts',
'this:blogger_getRecentPosts',
array('array', 'string', 'string', 'string', 'string', 'int'),
'retrieves a list of posts (default 10)'
);
// metaWeblog API[http://www.xmlrpc.com/metaWeblogApi] - add as server capability
$this->capabilities['metaWeblog API'] = array(
'specUrl' => 'http://www.xmlrpc.com/metaWeblogApi',
'specVersion' => 1
);
// Implements also MovableType extension of the API methods
$this->addCallback(
'metaWeblog.getPost',
'this:metaWeblog_getPost',
array('struct', 'string', 'string', 'string'),
'retrieves contents for the given postid'
);
$this->addCallback(
'metaWeblog.newPost',
'this:metaWeblog_newPost',
array('string', 'string', 'string', 'string', 'struct', 'boolean'),
'creates a new post'
);
$this->addCallback(
'metaWeblog.editPost',
'this:metaWeblog_editPost',
array('boolean', 'string', 'string', 'string', 'struct', 'boolean'),
'creates a new post'
);
$this->addCallback(
'metaWeblog.getCategories',
'this:metaWeblog_getCategories',
array('struct', 'string', 'string', 'string'),
'retrieves a list of categories for the current blog'
);
$this->addCallback(
'metaWeblog.getRecentPosts',
'this:metaWeblog_getRecentPosts',
array('array', 'string', 'string', 'string', 'int'),
'retrieves a given number of recent posts'
);
#TODO: metaWeblog.newMediaObject (blogid, username, password, struct) returns struct
// MovableType API[] - add as server capability
$this->capabilities['MovableType API'] = array(
'specUrl' => 'http://www.sixapart.com/movabletype/docs/mtmanual_programmatic.html#xmlrpc%20api',
'specVersion' => 1
);
// Not completelly implemented.
$this->addCallback(
'mt.getRecentPostTitles',
'this:mt_getRecentPostTitles',
array('array', 'string', 'string', 'string', 'id'),
'returns a bandwidth-friendly list of the most recent posts in the system'
);
$this->addCallback(
'mt.getCategoryList',
'this:mt_getCategoryList',
array('array', 'string', 'string', 'string'),
'returns a list of all categories defined in the weblog'
);
$this->addCallback(
'mt.supportedMethods',
'this:listMethods',
array('array'),
'return the XML-RPC Methods supported by the server(Redundant).'
);
$this->addCallback(
'mt.supportedTextFilters',
'this:mt_supportedTextFilters',
array('array'),
'return the format filters suported by the server.'
);
$this->addCallback(
'mt.getPostCategories',
'this:mt_getPostCategories',
array('array', 'string', 'string', 'string'),
'returns a list of all categories for the given article'
);
$this->addCallback(
'mt.setPostCategories',
'this:mt_setPostCategories',
array('boolean', 'string', 'string', 'string', 'array'),
'sets categories for the given article'
);
$this->addCallback(
'mt.publishPost',
'this:mt_publishPost',
array('boolean', 'string', 'string', 'string'),
'changes the status of the current article to published'
);
}
}
// Override serve method in order to keep requests logs too
// while dealing with unknown clients
function serve($data = false)
{
if (!$data)
{
global $HTTP_RAW_POST_DATA;
if (!$HTTP_RAW_POST_DATA)
{
// RSD lets them find us via GET requests
$this->rsd();
exit;
}
$rx = '/<?xml.*encoding=['"](.*?)['"].*?>/m';
// first, handle the known UAs in order to serve proper content
if (strpos('w.bloggar', $_SERVER['HTTP_USER_AGENT']) !== false)
{
$encoding = 'iso-8859-1';
}
// find for supplied encoding before to try other things
elseif (preg_match($rx, $HTTP_RAW_POST_DATA, $xml_enc))
{
$encoding = strtolower($xml_enc[1]);
}
// try utf-8 detect
elseif (preg_match('/^([x00-x7f]|[xc2-xdf][x80-xbf]|xe0[xa0-xbf][x80-xbf]|[xe1-xec][x80-xbf]{2}|xed[x80-x9f][x80-xbf]|[xee-xef][x80-xbf]{2}|f0[x90-xbf][x80-xbf]{2}|[xf1-xf3][x80-xbf]{3}|xf4[x80-x8f][x80-xbf]{2})*$/', $HTTP_RAW_POST_DATA) === 1)
{
$encoding = 'utf-8';
}
// otherwise, use iso-8859-1
else
{
$encoding = 'iso-8859-1';
}
switch ($encoding)
{
case 'utf-8':
$data = $HTTP_RAW_POST_DATA;
break;
case 'iso-8859-1':
#TODO: if utf8 conversion fails, throw: 32701 ---> parse error. unsupported encoding?
#see: http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php
// this will fail on parser if utf8_encode is unavailiable
$data = (function_exists('utf8_encode') && is_callable('utf8_encode'))? utf8_encode($HTTP_RAW_POST_DATA) : $HTTP_RAW_POST_DATA;
break;
default:
#TODO: if utf8 conversion fails, throw: 32701 ---> parse error. unsupported encoding?
// this will fail on parser if mb_convert_encoding is unavailiable
$data = (function_exists('mb_convert_encoding') && is_callable('mb_convert_encoding'))? mb_convert_encoding($HTTP_RAW_POST_DATA, 'utf-8', $encoding) : $HTTP_RAW_POST_DATA;
break;
}
}
$this->message = new IXR_Message($data);
if (!$this->message->parse())
{
$this->error(-32700, 'parse error. not well formed');
}
if ($this->message->messageType != 'methodCall')
{
$this->error(-32600, 'server error. invalid xml-rpc. not conforming to spec. Request must be a methodCall');
}
$result = $this->call($this->message->methodName, $this->message->params);
// Is the result an error?
if (is_a($result, 'IXR_Error'))
{
$this->error($result);
}
// Encode the result
$r = new IXR_Value($result);
$resultxml = $r->getXml();
// Create the XML
$xml = <<<EOD
<methodResponse>
<params>
<param>
<value>
$resultxml
</value>
</param>
</params>
</methodResponse>
EOD;
return $this->output($xml, $encoding);
}
// Override default utf-8 output, if needed
function output($xml, $enc = 'utf-8')
{
// Be kind with non-utf-8 capable clients
if ($enc != 'utf-8')
{
if ($enc == 'iso-8859-1' && function_exists('utf8_decode') && is_callable('utf8_decode'))
{
$xml = utf8_decode($xml);
}
elseif (function_exists('mb_convert_encoding') && is_callable('mb_convert_encoding'))
{
$xml = mb_convert_encoding($xml, $enc, 'utf-8');
}
else
{
# TODO: shouldn't this throw an error instead of serving non-utf8 content as utf8?
// if no decoding possible, serve contents as utf-8
$enc = 'utf-8';
}
}
$xml = '<?xml version="1.0" encoding="'.$enc.'" ?>'.n.$xml;
$length = strlen($xml);
header('Connection: close');
header('Content-Length: '.$length);
header('Content-Type: text/xml charset='.$enc);
header('Date: '.date('r'));
echo $xml;
exit;
}
//---------------------------------------------------------
// Really Simple Discoverability 1.0 response
function rsd()
{
global $enable_xmlrpc_server;
if ($enable_xmlrpc_server)
{
$this->output(
tag(
n.tag(
n.tag('Textpattern', 'engineName').
n.tag('http://textpattern.com/', 'engineLink').
n.tag(hu, 'homePageLink').
n.tag(
n.'<api name="Movable Type" blogID="" preferred="true" apiLink="'.txrpcpath.'" />'.
n.'<api name="MetaWeblog" blogID="" preferred="false" apiLink="'.txrpcpath.'" />'.
n.'<api name="Blogger" blogID="" preferred="false" apiLink="'.txrpcpath.'" />'.n,
'apis').n,
'service').n,
'rsd', ' version="1.0" xmlns="http://archipelago.phrasewise.com/rsd"')
);
}
else
{
header('Status: 501 Not Implemented');
header('HTTP/1.1 501 Not Implemented');
die('Not Implemented');
}
}
//---------------------------------------------------------
// Blogger API
function blogger_newPost($params)
{
list($appkey, $blogid, $username, $password, $content, $publish) = $params;
$txp = new TXP_Wrapper($username, $password);
if (!$txp->loggedin)
{
return new IXR_Error(100, gTxt('bad_login'));
}
$contents = $this->_getBloggerContents($content);
$contents['Section'] = $blogid;
$contents['Status'] = $publish ? '4' : '1';
$rs = $txp->newArticle($contents);
if (false === $rs)
{
return new IXR_Error(201, gTxt('problem_creating_article'));
}
return intval($rs);
}
function blogger_editPost($params)
{
list($appkey, $postid, $username, $password, $content, $publish) = $params;
$txp = new TXP_Wrapper($username, $password);
if (!$txp->loggedin)
{
return new IXR_Error(100, gTxt('bad_login'));
}
$id = $txp->getArticleID($postid, 'ID');
if (!$id)
{
return new IXR_Error(404, gTxt('invalid_article_id'));
}
$contents = $this->_getBloggerContents($content);
$contents['Status'] = $publish ? '4' : '1';
$rs = $txp->updateArticleID($postid, $contents);
if (false === $rs)
{
return new IXR_Error(202, gTxt('problem_updating_article'));
}
return true;
}
function blogger_getUsersBlogs($params)
{
list($appkey, $username, $password) = $params;
global $permlink_mode;
$txp = new TXP_Wrapper($username, $password);
if (!$txp->loggedin)
{
return new IXR_Error(100, gTxt('bad_login'));
}
$rs = $txp->getSectionsList();
if (false === $rs)
{
return new IXR_Error(203, gTxt('problem_retrieving_sections'));
}
$sections = array();
foreach ($rs as $section)
{
$sections[] = array(
'blogid' => $section['name'],
'blogName' => $section['title'],
'url' => pagelinkurl(array('s' => $section['name']))
);
}
return $sections;
}
function blogger_getUserInfo($params)
{
list($appkey, $username, $password) = $params;
$txp = new TXP_Wrapper($username, $password);
if (!$txp->loggedin)
{
return new IXR_Error(100, gTxt('bad_login'));
}
$rs = $txp->getUser();
if (!$rs)
{
return new IXR_Error(204, gTxt('unable_retrieve_user'));
}
extract($rs);
if (strpos($RealName, ' ') != 0)
{
list($firstname, $lastname) = explode(' ', $RealName);
}
else
{
$firstname = $RealName;
$lastname = '';
}
$uinfo = array(
'userid' => $user_id,
'firstname' => $firstname,
'lastname' => $lastname,
'nickname' => $name,
'email' => $email,
'url' => hu
);
return $uinfo;
}
function blogger_getTemplate($params)
{
list($appkey, $blogid, $username, $password, $templateType) = $params;
$txp = new TXP_Wrapper($username, $password);
if (!$txp->loggedin)
{
return new IXR_Error(100, gTxt('bad_login'));
}
if ($templateType == 'archiveIndex' && $blogid != 'default')
{
$section = $txp->getSection($blogid);
if (!$section)
{
return new IXR_Error(208, gTxt('unable_retrieve_template'));
}
$name = $section['page'];
}
else
{
$name = 'default';
}
$rs = $txp->getTemplate($name);
if (!$rs)
{
return new IXR_Error(208, gTxt('unable_retrieve_template'));
}
return $rs;
}
function blogger_setTemplate($params)
{
list($appkey, $blogid, $username, $password, $template, $templateType) = $params;
$txp = new TXP_Wrapper($username, $password);
if (!$txp->loggedin)
{
return new IXR_Error(100, gTxt('bad_login'));
}
if ($templateType == 'archiveIndex' && $blogid != 'default')
{
$section = $txp->getSection($blogid);
if (!$section)
{
return new IXR_Error(209, gTxt('unable_set_template'));
}
$name = $section['page'];
}
else
{
$name = 'default';
}
$rs = $txp->setTemplate($name, $template);
if (!$rs)
{
return new IXR_Error(209, gTxt('unable_set_template'));
}
return true;
}
//---------------------------------------------------------
// Blogger 2.0
function blogger_getPost($params)
{
list($appkey, $postid, $username, $password) = $params;
$txp = new TXP_Wrapper($username, $password);
if (!$txp->loggedin)
{
return new IXR_Error(100, gTxt('bad_login'));
}
$rs = $txp->getArticleID($postid, 'ID, Body, AuthorId, unix_timestamp(Posted) as uPosted');
if (!$rs)
{
return new IXR_Error(205, gTxt('problem_retrieving_article'));
}
$out = array(
'content' => $rs['Body'],
'userId' => $rs['AuthorId'],
'postId' => $rs['ID'],
'dateCreated' => new IXR_Date($rs['uPosted'] + tz_offset())
);
return $out;
}
function blogger_deletePost($params)
{
list($appkey, $postid, $username, $password, $publish) = $params;
$txp = new TXP_Wrapper($username, $password);
if (!$txp->loggedin)
{
return new IXR_Error(100, gTxt('bad_login'));
}
// Always delete, no matter of publish
$rs = $txp->deleteArticleID($postid);
if (!$rs)
{
return new IXR_Error(206, gTxt('problem_deleting_article'));
}
return $rs;
}
function blogger_getRecentPosts($params)
{
list($appkey, $blogid, $username, $password, $numberOfPosts) = $params;
$txp = new TXP_Wrapper($username, $password);
if (!$txp->loggedin)
{
return new IXR_Error(100, gTxt('bad_login'));
}
$articles = $txp->getArticleList('ID, Body, AuthorId, unix_timestamp(Posted) as uPosted', "Section='".doSlash($blogid)."'", '0', $numberOfPosts, false);
if (false === $articles)
{
return new IXR_Error(207, gTxt('problem_getting_articles'));
}
foreach ($articles as $rs)
{
$out[] = array(
'content' => $rs['Body'],
'userId' => $rs['AuthorId'],
'postId' => $rs['ID'],
'dateCreated' => new IXR_Date($rs['uPosted'] + tz_offset())
);
}
return $out;
}
//---------------------------------------------------------
// metaWeblog API
function metaWeblog_getPost($params)
{
list($postid, $username, $password) = $params;
$txp = new TXP_Wrapper($username, $password);
if (!$txp->loggedin)
{
return new IXR_Error(100, gTxt('bad_login'));
}
$rs = $txp->getArticleID($postid, 'ID, Title, Body, Excerpt, Annotate, Keywords, Section, Category1, Category2, textile_body, url_title, unix_timestamp(Posted) as uPosted');
if (!$rs)
{
return new IXR_Error(205, gTxt('problem_retrieving_article'));
}
return $this->_buildMetaWeblogStruct($rs, $txp);
}
function metaWeblog_newPost($params)
{
list($blogid, $username, $password, $struct, $publish) = $params;
$txp = new TXP_Wrapper($username, $password);
if (!$txp->loggedin)
{
return new IXR_Error(100, gTxt('bad_login'));
}
$contents = $this->_getMetaWeblogContents($struct, $publish, $txp);
$contents['Section'] = $blogid;
$rs = $txp->newArticle($contents);
if (false === $rs)
{
return new IXR_Error(201, gTxt('problem_creating_article'));
}
#TODO: why "" quoted $rs?
return "$rs";
}
function metaWeblog_editPost($params)
{
list($postid, $username, $password, $struct, $publish) = $params;
$txp = new TXP_Wrapper($username, $password);
if (!$txp->loggedin)
{
return new IXR_Error(100, gTxt('bad_login'));
}
$contents = $this->_getMetaWeblogContents($struct, $publish, $txp);
$rs = $txp->updateArticleID($postid, $contents);
if (false === $rs)
{
return new IXR_Error(201, gTxt('problem_updating_article'));
}
return true;
}
function metaWeblog_getCategories($params)
{
list($blogid, $username, $password) = $params;
global $permlink_mode;
$txp = new TXP_Wrapper($username, $password);
if (!$txp->loggedin)
{
return new IXR_Error(100, gTxt('bad_login'));
}
$rs = $txp->getCategoryList();
if (false === $rs)
{
return new IXR_Error(210, gTxt('problem_retrieving_categories'));
}
$cats = array();
foreach ($rs as $c)
{
$cats[] = array(
'categoryName' => $c['title'],
'description' => $c['title'],
'htmlUrl' => pagelinkurl(array('c' => $c['name'])),
'rssUrl' => hu.'?rss=1&category='.$c['name']
);
}
return $cats;
}
function metaWeblog_getRecentPosts($params)
{
list($blogid, $username, $password, $numberOfPosts) = $params;
$txp = new TXP_Wrapper($username, $password);
if (!$txp->loggedin)
{
return new IXR_Error(100, gTxt('bad_login'));
}
$articles = $txp->getArticleList('ID, Title, url_title, Body, Excerpt, Annotate, Keywords, Section, Category1, Category2, textile_body, AuthorID, unix_timestamp(Posted) as uPosted',
"Section='".doSlash($blogid)."'", '0', $numberOfPosts, false);
if (false === $articles)
{
return new IXR_Error(207, gTxt('problem_getting_articles'));
}
$out = array();
foreach ($articles as $rs)
{
$out[] = $this->_buildMetaWeblogStruct($rs, $txp);
}
return $out;
}
//---------------------------------------------------------
// MovableType API
function mt_getRecentPostTitles($params)
{
list($blogid, $username, $password, $numberOfPosts) = $params;
global $prefs;
$txp = new TXP_Wrapper($username, $password);
if (!$txp->loggedin)
{
return new IXR_Error(100, gTxt('bad_login'));
}
$articles = $txp->getArticleList('ID, Title, AuthorID, unix_timestamp(Posted) as uPosted', "Section='".doSlash($blogid)."'", '0', $numberOfPosts, false);
if (false === $articles)
{
return new IXR_Error(207, gTxt('problem_getting_articles'));
}
extract($prefs);
$out = array();
foreach ($articles as $rs)
{
$out[] = array(
'userid' => $username,
'postid' => $rs['ID'],
'dateCreated' => new IXR_Date($rs['uPosted'] + tz_offset()),
'title' => $rs['Title'],
);
}
return $out;
}
function mt_getCategoryList($params)
{
list($blogid, $username, $password) = $params;
$txp = new TXP_Wrapper($username, $password);
if (!$txp->loggedin)
{
return new IXR_Error(100, gTxt('bad_login'));
}
$rs = $txp->getCategoryList();
if (false === $rs)
{
return new IXR_Error(210, gTxt('problem_retrieving_categories'));
}
$cats = array();
foreach ($rs as $c)
{
$cats[] = array(
'categoryName' => $c['title'],
'categoryId' => $c['id'],
);
}
return $cats;
}
function mt_supportedTextFilters($params)
{
$filters = array(
array('key' => '0', 'label' => 'LEAVE_TEXT_UNTOUCHED'),
array('key' => '1', 'label' => 'USE_TEXTILE'),
array('key' => '2', 'label' => 'CONVERT_LINEBREAKS'),
);
return $filters;
}
function mt_getPostCategories($params)
{
list($postid, $username, $password) = $params;
$txp = new TXP_Wrapper($username, $password);
if (!$txp->loggedin)
{
return new IXR_Error(100, gTxt('bad_login'));
}
$post = $txp->getArticleID($postid, 'Category1, Category2');
if (!$post)
{
return new IXR_Error(211, gTxt('problem_retrieving_article_categories'));
}
$out = array();
$isPrimary = true;
$cats[] = $post['Category1'];
$cats[] = $post['Category2'];
foreach ($cats as $category)
{
if (!empty($category))
{
$rs = $txp->getCategory($category);
#TODO: remove?
// if (!$rs) return new IXR_Error(212, gTxt('problem_retrieving_category_info'));
$ct['categoryId'] = $rs['id'];
$ct['categoryName'] = $rs['title'];
$ct['isPrimary'] = $isPrimary;
$out[] = $ct;
}
if ($isPrimary) $isPrimary = false;
}
return $out;
}
#TODO: explain what 'expecific' is ;)
// supported to avoid some client expecific behaviour
function mt_publishPost($params)
{
list($postid, $username, $password) = $params;
$txp = new TXP_Wrapper($username, $password);
if (!$txp->loggedin)
{
return new IXR_Error(100, gTxt('bad_login'));
}
$published = $txp->updateArticleField($postid, 'Status', '4');
if (!$published)
{
return new IXR_Error(201, gTxt('problem_updating_article'));
}
return true;
}
function mt_setPostCategories($params)
{
list($postid, $username, $password, $categories) = $params;
$txp = new TXP_Wrapper($username, $password);
if (!$txp->loggedin)
{
return new IXR_Error(100, gTxt('bad_login'));
}
$Category1 = '';
$Category2 = '';
foreach ($categories as $category)
{
extract($category);
$rs = $txp->getCategoryId($categoryId);
if (!$rs)
{
return new IXR_Error(213, gTxt('trying_to_assign_unexisting_category_to_the_article'));
}
if (empty($Category1))
{
$Category1 = $rs['name'];
}
else
{
$Category2 = $rs['name'];
}
}
$ct1 = $txp->updateArticleField($postid, 'Category1', $Category1);
$ct2 = $txp->updateArticleField($postid, 'Category2', $Category2);
if (!$ct1 || !$ct2)
{
return new IXR_Error(214, gTxt('problem_saving_article_categories'));
}
return true;
}
#TODO ???
// MediaObjects
/*
metaWeblog.newMediaObject
Description: Uploads a file to your webserver.
Parameters: String blogid, String username, String password, struct file
Return value: URL to the uploaded file.
Notes: the struct file should contain two keys: base64 bits (the base64-encoded contents of the file)
and String name (the name of the file). The type key (media type of the file) is currently ignored.
*/
//code refactoring for blogger_newPost & blogger_editPost
function _getBloggerContents($content)
{
$body = $content;
// Trick to add title, category and excerpts using XML-RPC
if (preg_match('/<title>(.*)</title>(.*)/s', $content, $matches))
{
$body = $matches[2];
$title = $matches[1];
}
$contents = array(
'Body' => str_replace('n', n, $body)
);
if (isset($title)) $contents['Title'] = $title;
return $contents;
}
//code refactoring for metaWeblog_newPost & metaweblog_EditPost
function _getMetaWeblogContents($struct, $publish, $txp)
{
global $gmtoffset, $is_dst;
$contents = array(
'Body' => str_replace('n', n, $struct['description']),
'Status' => $publish ? '4' : '1',
'Title' => $struct['title']
);
if (!empty($struct['categories']))
{
if (!empty($struct['categories'][0]))
{
$c = $txp->getCategoryTitle($struct['categories'][0]);
$contents['Category1'] = $c['name'];
}
if (!empty($struct['categories'][1]))
{
$c = $txp->getCategoryTitle($struct['categories'][1]);
$contents['Category2'] = $c['name'];
}
}
if (isset($struct['date_created_gmt']))
{
$struct['dateCreated'] = $struct['date_created_gmt'];
$struct['dateCreated']->tz = 'Z'; // force GMT timezone
}
if (isset($struct['dateCreated']))
{
if ($struct['dateCreated']->tz == 'Z')
{
// GMT-based posting time; transform into server time zone
$posted = $struct['dateCreated']->getTimestamp() - tz_offset() + $gmtoffset + ($is_dst ? 3600 : 0);
}
elseif (!$struct['dateCreated']->tz)
{
// posting in an unspecified time zone: Assume site time.
$posted = $struct['dateCreated']->getTimestamp() - tz_offset();
}
else
{
// numeric time zone offsets
if (preg_match('/([+-][0-9]{2})([0-9]{2})/', $struct['dateCreated']->tz, $t))
{
$tz = $t[1] * 3600 + $t[2] * 60;
$posted = $struct['dateCreated']->getTimestamp() - tz_offset() + $gmtoffset + ($is_dst ? 3600 : 0) - $tz;
}
}
}
if (isset($posted)) $contents['Posted'] = date('Y-m-d H:i:s', $posted);
// MovableType Implementation Add ons
if (isset($struct['mt_allow_comments']))
{
$contents['Annotate'] = $struct['mt_allow_comments'];
}
if (isset($struct['mt_convert_breaks']))
{
$contents['textile_body'] = $contents['textile_excerpt'] = intval($struct['mt_convert_breaks']);
}
if (isset($struct['mt_text_more']))
{
$contents['Body'] .= n.n.str_replace('n', n ,$struct['mt_text_more']);
}
if (isset($struct['mt_excerpt']))
{
$contents['Excerpt'] = str_replace('n', n, $struct['mt_excerpt']);
}
if (isset($struct['mt_keywords']))
{
$contents['Keywords'] = $struct['mt_keywords'];
}
if (isset($struct['mt_basename']))
{
$contents['url_title'] = stripSpace($struct['mt_basename']);
}
elseif (isset($struct['wp_slug']))
{
$contents['url_title'] = stripSpace($struct['wp_slug']);
}
return $contents;
}
// common code to metaWeblog_getPost and metaWeblog_getRecentPosts
// could not be this placed on a different file from taghandlers?
// remove if it is the case
function _buildMetaWeblogStruct($rs, $txp)
{
global $permlink_mode, $is_dst, $gmtoffset;
switch ($permlink_mode)
{
case 'section_id_title':
$url = hu.join('/', array($rs['Section'], $rs['ID'], $rs['url_title']));
break;
case 'year_month_day_title':
$url = hu.join('/', array(
date("Y", $rs['uPosted']),
date("m", $rs['uPosted']),
date("d", $rs['uPosted']),
$rs['url_title']
));
break;
case 'title_only':
$url = hu.$rs['url_title'];
break;
case 'section_title':
$url = hu.join('/', array($rs['Section'], $rs['url_title']));
break;
case 'id_title':
$url = hu.join('/', array($rs['ID'], $rs['url_title']));
break;
default:
//assume messy mode?
$url = hu.'?id='.$rs['ID'];
break;
}
$cat = $txp->getCategory($rs['Category1']);
$cat1 = $cat['title'];
$cat = $txp->getCategory($rs['Category2']);
$cat2 = $cat['title'];
$out = array(
'categories' => array($cat1, $cat2),
'description' => $rs['Body'],
'userid' => $txp->txp_user,
'postid' => $rs['ID'],
'dateCreated' => new IXR_Date($rs['uPosted'] + tz_offset() - $gmtoffset - ($is_dst ? 3600 : 0)),
'link' => $url,
'permaLink' => $url,
'title' => $rs['Title'],
);
$out['dateCreated']->tz = 'Z'; // GMT
// MovableType Implementation Add ons
if (isset($rs['Annotate']) && !empty($rs['Annotate']))
{
$out['mt_allow_comments'] = intval($rs['Annotate']);
}
if (isset($rs['textile_body']) && !empty($rs['textile_body']))
{
$out['mt_convert_breaks'] = strval($rs['textile_body']);
}
if (isset($rs['Excerpt']) && !empty($rs['Excerpt']))
{
$out['mt_excerpt'] = $rs['Excerpt'];
}
if (isset($rs['Keywords']) && !empty($rs['Keywords']))
{
$out['mt_keywords'] = $rs['Keywords'];
}
if (isset($rs['url_title']) && !empty($rs['url_title']))
{
$out['mt_basename'] = $out['wp_slug'] = $rs['url_title'];
}
return $out;
}
}
?>