2 Star 0 Fork 0

杀神启示 / emlog5

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
xmlrpc.php 20.52 KB
一键复制 编辑 原始数据 按行查看 历史
杀神启示 提交于 2016-12-03 21:50 . init repo
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770
<?php
/**
* xmlrpc服务接口
*
* @copyright (c) Emlog All Rights Reserved
*/
ob_start();
define('EMLOG_ROOT', dirname(__FILE__));
require_once EMLOG_ROOT . '/config.php';
require_once EMLOG_ROOT . '/include/lib/function.base.php';
$api_methods = array(
// metaWeblog 接口
'metaWeblog.newPost' => 'mw_newPost',
'metaWeblog.editPost' => 'mw_editPost',
'metaWeblog.getPost' => 'mw_getPost',
'metaWeblog.getRecentPosts' => 'mw_getRecentPosts',
'metaWeblog.getCategories' => 'mw_getCategories',
'metaWeblog.newMediaObject' => 'mw_newMediaObject',
// blogger 接口
'blogger.deletePost' => 'mw_deletePost',
'blogger.getUsersBlogs' => 'blogger_getUsersBlogs'
);
$DB = Database::getInstance();
$options_cache = Cache::getInstance()->readCache('options');
// 有些基于浏览器的客户端会发送cookie,我们不需要它们
$_COOKIE = array();
// PHP 5.2.2 以下版本有一个bug, 常量 $HTTP_RAW_POST_DATA 系统不会自动生成
if (!isset($HTTP_RAW_POST_DATA)) {
$HTTP_RAW_POST_DATA = file_get_contents('php://input');
}
// 修复mozBlog或其他个例不兼容xml标签不在第一行的情况
if (isset($HTTP_RAW_POST_DATA))
$HTTP_RAW_POST_DATA = trim($HTTP_RAW_POST_DATA);
// 向客户端发送api支持信息
if (isset($_GET['rsd'])) {
header('Content-Type: text/xml; charset=utf-8', true);
echo '<?xml version="1.0" encoding="utf-8"?>
<rsd version="1.0" xmlns="http://archipelago.phrasewise.com/rsd">
<service>
<engineName>emlog</engineName>
<engineLink>http://emlog.net/</engineLink>
<homePageLink>' . $options_cache['blogurl'] . '</homePageLink>
<apis>
<api name="MetaWeblog" blogID="1" preferred="true" apiLink="' . $options_cache['blogurl'] . 'xmlrpc.php" />
<api name="Blogger" blogID="1" preferred="false" apiLink="' . $options_cache['blogurl'] . 'xmlrpc.php" />
</apis>
</service>
</rsd>
';
exit;
}
if ($options_cache['isxmlrpcenable'] == 'n') {
error_message(500, '提示:站点XMLRPC服务未开启.');
}
if (!$HTTP_RAW_POST_DATA) {
error_message(500, '错误:XML-RPC服务器只能接受POST数据');
}
$data = $HTTP_RAW_POST_DATA;
$current_tag_contents = $current_tag = $message_type = $method_name = null;
$array_structs_types = $array_structs = $current_struct_name_array = $params = array();
$data = preg_replace('/<\?xml.*?\?' . '>/', '', $data);
if (trim($data) == '') {
error_message(500, '错误:提交数据内容为空');
}
// 兼容php libxml模块2.7.0-2.7.3版本解析xml丢失html标签括号的bug
if (in_array(LIBXML_DOTTED_VERSION, array('2.7.0', '2.7.1', '2.7.2', '2.7.3'))) {
$data = str_replace(array('&lt;', '&gt;', '&amp;'), array('&#60;', '&#62;' , '&#38;'), $data);
}
$parser = xml_parser_create();
xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, false);
xml_set_element_handler($parser, 'tag_open', 'tag_close');
xml_set_character_data_handler($parser, 'cdata');
if (!xml_parse($parser, $data)) {
die;
}
xml_parser_free($parser);
if (!array_key_exists($method_name, $api_methods)) die('unknow request');
call_user_func($api_methods[$method_name], $params);
/**
* 读取站点信息
*/
function blogger_getUsersBlogs() {
global $options_cache;
$xml = "
<array>
<data>
<value>
<struct>
<member>
<name>url</name>
<value>
<string>{$options_cache['blogurl']}</string>
</value>
</member>
<member>
<name>blogid</name>
<value>
<string>1</string>
</value>
</member>
<member>
<name>blogName</name>
<value>
<string>{$options_cache['blogname']}</string>
</value>
</member>
</struct>
</value>
</data>
</array>";
response($xml);
}
/**
* 删除文章
*/
function mw_deletePost($args) {
escape($args);
$id = intval($args[1]);
$user = login($args[2], $args[3]);
define('UID', $user['uid']);
$Log_Model = new Log_Model();
$Log_Model->deleteLog($id);
Cache::getInstance()->updateCache();
response('<boolean>1</boolean>');
}
/**
* 保存新文章
*/
function mw_newPost($args) {
global $options_cache;
escape($args);
$user = login($args[1], $args[2]);
define('UID', $user['uid']);
$id = intval($args[0]);
$username = $args[1];
$password = $args[2];
$data = $args[3];
$publish = $args[4];
$update_data['title'] = $data['title'];
$update_data['content'] = htmlspecialchars_decode($data['description']);
$update_data['author'] = UID;
$update_data['hide'] = $publish == 1 ? 'n' : 'y';
$update_data['excerpt'] = '';
// 只取第一个分类
$sort_name = isset($data['categories']) && isset($data['categories'][0]) ? $data['categories'][0] : '';
$Sort_Model = new Sort_Model();
$sorts = $Sort_Model->getSorts();
$update_data['sortid'] = '-1';
foreach ($sorts as $sort) {
if ($sort_name == $sort['sortname']) {
$update_data['sortid'] = $sort['sid'];
break;
}
}
// 发布时间
if (isset($data['dateCreated']) && is_object($data['dateCreated'])) {
$update_data['date'] = @gmmktime($data['dateCreated']->hour, $data['dateCreated']->minute , $data['dateCreated']->second , $data['dateCreated']->month , $data['dateCreated']->day , $data['dateCreated']->year) - $options_cache['timezone'] * 3600;
}else {
$update_data['date'] = time();
}
// 更新数据
$Log_Model = new Log_Model();
$new_id = $Log_Model->addlog($update_data);
// 更新标签
if (isset($data['mt_keywords']) && !empty($data['mt_keywords'])) {
$Tag_Model = new Tag_Model();
$Tag_Model->addTag($data['mt_keywords'], $new_id);
unset($Tag_Model);
}
// 更新缓存
Cache::getInstance()->updateCache();
response("<i4>$new_id</i4>");
}
/**
* 更新文章
*/
function mw_editPost($args) {
global $options_cache;
escape($args);
$username = $args[1];
$password = $args[2];
$user = login($username, $password);
define('UID', $user['uid']);
// 接受参数
$id = intval($args[0]);
$username = $args[1];
$password = $args[2];
$data = $args[3];
$publish = $args[4];
$update_data['title'] = $data['title'];
$update_data['content'] = htmlspecialchars_decode($data['description']);
$update_data['author'] = UID;
$update_data['hide'] = $publish == 1 ? 'n' : 'y';
// 根据分类名称取分类id,注意只取第一个分类
$sort_name = isset($data['categories']) && isset($data['categories'][0]) ? $data['categories'][0] : '';
$Sort_Model = new Sort_Model();
$sorts = $Sort_Model->getSorts();
unset($Sort_Model);
$update_data['sortid'] = '-1';
foreach ($sorts as $sort) {
if ($sort_name == $sort['sortname']) {
$update_data['sortid'] = $sort['sid'];
break;
}
}
// 发布时间
if (isset($data['dateCreated']) && is_object($data['dateCreated'])) {
$update_data['date'] = @gmmktime($data['dateCreated']->hour, $data['dateCreated']->minute , $data['dateCreated']->second , $data['dateCreated']->month , $data['dateCreated']->day , $data['dateCreated']->year) - $options_cache['timezone'] * 3600;
}
// 更新数据
$Log_Model = new Log_Model();
$Log_Model->updateLog($update_data, $id);
// 更新标签
if (isset($data['mt_keywords']) && !empty($data['mt_keywords'])) {
$Tag_Model = new Tag_Model();
$Tag_Model->updateTag($data['mt_keywords'], $id);
}
// 更新缓存
Cache::getInstance()->updateCache();
response('<boolean>1</boolean>');
}
/**
* 取得站点分类
*/
function mw_getCategories($args) {
escape($args);
$username = $args[1];
$password = $args[2];
login($username, $password);
$Sort_Model = new Sort_Model();
$sorts = $Sort_Model->getSorts();
unset($Sort_Model);
$xml = '';
foreach ($sorts as $sort) {
$xml .= "
<value>
<struct>
<member>
<name>description</name>
<value>{$sort['sortname']}</value>
</member>
<member>
<name>title</name>
<value>{$sort['sortname']}</value>
</member>
</struct>
</value>
";
}
$xml = "<array><data>$xml</data></array>";
response($xml);
}
/**
* 读取文章信息
*/
function mw_getPost($args) {
global $options_cache;
escape($args);
$post_ID = intval($args[0]);
$username = $args[1];
$password = $args[2];
$user = login($username, $password);
$Log_Model = new Log_Model();
define('UID', $user['uid']);
$post = $Log_Model->getOneLogForAdmin($post_ID);
if (empty($post)) return error_message(404, '对不起,您访问的文章不存在');
$log_cache_tags = Cache::getInstance()->readCache('logtags');
$tags = '';
if (!empty($log_cache_tags[$post['gid']])) {
foreach ($log_cache_tags[$post['gid']] as $tag) {
$tags[] = $tag['tagname'];
}
$tags = implode(',', $tags);
}
$Sort_Model = new Sort_Model();
$sort_name = $Sort_Model->getSortName($post['sortid']);
$post['date'] = getIso($post['date']);
$xml = "
<struct>
<member>
<name>categories</name>
<value>
<array>
<data>
<value>{$sort_name}</value>
</data>
</array>
</value>
</member>
<member>
<name>mt_keywords</name>
<value>
<string>$tags</string>
</value>
</member>
<member>
<name>dateCreated</name>
<value>
<dateTime.iso8601>{$post['date']}</dateTime.iso8601>
</value>
</member>
<member>
<name>description</name>
<value>
{$post['content']}
</value>
</member>
<member>
<name>link</name>
<value>{$options_cache['blogurl']}index.php?post={$post['gid']}</value>
</member>
<member>
<name>postid</name>
<value>
<string>{$post['gid']}</string>
</value>
</member>
<member>
<name>title</name>
<value>{$post['title']}</value>
</member>
<member>
<name>publish</name>
<value>
<boolean>1</boolean>
</value>
</member>
</struct>
";
response($xml);
}
function mw_getRecentPosts($args) {
escape($args);
$db = Database::getInstance();
$username = $args[1];
$password = $args[2];
$num_posts = intval($args[3]);
$num_posts == 0 && $num_posts = 1;
$user = login($username, $password);
$query = $db->query('SELECT gid,title,date,content,author,sortid FROM ' . DB_PREFIX . 'blog ORDER BY date DESC LIMIT 0,' . $num_posts);
$xml = '';
$recent_posts = array();
$log_cache_tags = Cache::getInstance()->readCache('logtags');
while ($post = $db->fetch_array($query)) {
$post['title'] = htmlspecialchars($post['title']);
$post['content'] = htmlspecialchars($post['content']);
$post['date'] = getIso($post['date']);
$tags = '';
if (!empty($log_cache_tags[$post['gid']])) {
foreach ($log_cache_tags[$post['gid']] as $tag) {
$tags[] = $tag['tagname'];
}
$tags = implode(',', $tags);
}
$xml .= "<value>
<struct>
<member>
<name>title</name>
<value>
<string>{$post['title']}</string>
</value>
</member>
<member>
<name>description</name>
<value>
<string>{$post['content']}</string>
</value>
</member>
<member>
<name>dateCreated</name>
<value>
<dateTime.iso8601>{$post['date']}</dateTime.iso8601>
</value>
</member>
<member>
<name>categories</name>
<value>
<array>
<data>
<value><string></string></value>
</data>
</array>
</value>
</member>
<member>
<name>postid</name>
<value>
<string>{$post['gid']}</string>
</value>
</member>
<member>
<name>userid</name>
<value><string>1</string></value>
</member>
<member>
<name>publish</name>
<value>
<string>1</string>
</value>
</member>
<member>
<name>link</name>
<value><string>http://emlog.net/blog</string></value>
</member>
<member>
<name>mt_keywords</name>
<value>
<string>$tags</string>
</value>
</member>
</struct></value>";
}
if (empty($xml)) {
error_massage(404, '没有文章');
}
$xml = "<array><data>$xml</data></array>";
response($xml);
}
function mw_newMediaObject($args) {
global $options_cache;
escape($args[1]);
escape($args[2]);
$username = $args[1];
$password = $args[2];
$user = login($username, $password);
$file = $args[3];
if (!preg_match('/([^\/\:\*\?<>\|]+\.\w{2,6})|(\\{2}[^\/\:\*\?<>\|]+\.\w{2,6})/', $file['name'], $matches))
error_message(500, '文件错误');
$filename = $matches[0];
$bits = $file['bits'];
if (!empty($data["overwrite"]) && ($data["overwrite"] == true)) {
}
$att_type = Option::getAttType();
if (empty($filename))
error_message(500, '文件名错误');
$extension = strtolower(substr(strrchr($filename, "."), 1));
// 文件类型检测
if (!in_array($extension, $att_type)) {
error_message(500, '文件类型错误');
}
$uppath_root = substr(Option::UPLOADFILE_PATH, 1);
$uppath = $uppath_root . gmdate('Ym') . '/';
$fname = md5($filename) . gmdate('YmdHis') . '.' . $extension;
$attachpath = $uppath . $fname;
if (!is_dir($uppath_root)) {
umask(0);
$ret = @mkdir($uppath_root, 0777);
if ($ret === false) {
error_message(500, '创建文件上传目录失败');
}
}
if (!is_dir($uppath)) {
umask(0);
$ret = @mkdir($uppath, 0777);
if ($ret === false) {
error_message(500, '上传失败。文件上传目录(content/uploadfile)不可写');
}
}
$fp = @fopen($attachpath, 'wb');
if (!$fp)
error_message(500, '文件无法写入');
fwrite($fp, $bits);
fclose($fp);
doAction('xmlrpc_attach_upload', $attachpath);
// resizeImage
$imtype = array('jpg', 'png', 'jpeg');
$thum = $uppath . 'thum-' . $fname;
$thum_created = true;
if (Option::get('isthumbnail') && in_array($extension, $imtype) && function_exists('ImageCreate')) {
$max_w = Option::get('att_imgmaxw');
$max_h = Option::get('att_imgmaxh');
$size = chImageSize($attachpath, $max_w, $max_h);
$newwidth = $size['w'];
$newheight = $size['h'];
$w = $size['rc_w'];
$h = $size['rc_h'];
if ($w <= $max_w && $h <= $max_h) {
$thum_created = false;
}
if ($thum_created && ($extension == 'jpeg' || $extension == 'jpg')) {
if (function_exists('imagecreatefromjpeg')) {
$img = imagecreatefromjpeg($attachpath);
}else {
$thum_created = false;
}
}elseif ($thum_created && $extension == 'png') {
if (function_exists('imagecreatefrompng')) {
$img = imagecreatefrompng($attachpath);
}else {
$thum_created = false;
}
}
if ($thum_created && function_exists('imagecopyresampled')) {
$newim = imagecreatetruecolor($newwidth, $newheight);
imagecopyresampled($newim, $img, 0, 0, 0, 0, $newwidth, $newheight, $w, $h);
}elseif ($thum_created) {
$newim = imagecreate($newwidth, $newheight);
imagecopyresized($newim, $img, 0, 0, 0, 0, $newwidth, $newheight, $w, $h);
}
if ($thum_created && ($extension == 'jpeg' || $extension == 'jpg')) {
if (!imagejpeg($newim, $attachpath)) {
$thum_created = false;
}
}elseif ($thum_created && ($extension == 'png')) {
if (!imagepng($newim, $attachpath)) {
$thum_created = false;
}
}
if ($thum_created)
ImageDestroy($newim);
}
$img_url = $options_cache['blogurl'] . 'content/uploadfile/' . date('Ym') . '/' . $fname;
$xml = "
<struct>
<member>
<name>file</name>
<value>
<string>$fname</string>
</value>
</member>
<member>
<name>url</name>
<value>
<string>$img_url</string>
</value>
</member>
<member>
<name>type</name>
<value>
<string></string>
</value>
</member>
</struct>
";
response($xml);
}
function getIso($utctimestamp) {
$utctimestamp += Option::get('timezone') * 3600;
$year = gmdate('Y', $utctimestamp);
$month = gmdate('m', $utctimestamp);
$day = gmdate('d', $utctimestamp);
$hour = gmdate('H', $utctimestamp);
$minute = gmdate('i', $utctimestamp);
$second = gmdate('s', $utctimestamp);
return $year . $month . $day . 'T' . $hour . ':' . $minute . ':' . $second;
}
function login($username, $password) {
$username = addslashes($username);
$password = addslashes($password);
// 检查用户权限
if (true !== LoginAuth::checkUser($username, $password , '', 'n')) {
error_message(403, '用户名密码错误');
return false;
}
// 返回用户信息
return LoginAuth::getUserDataByLogin($username);
}
function escape(&$array) {
if (!is_array($array)) {
return(Database::getInstance()->escape_string($array));
}else {
foreach ((array) $array as $k => $v) {
if (is_array($v)) {
escape($array[$k]);
}else if (is_object($v)) {
// skip
}else {
$array[$k] = Database::getInstance()->escape_string($v);
}
}
}
}
function response($result_xml) {
$xml = "
<methodResponse>
<params>
<param>
<value>
$result_xml
</value>
</param>
</params>
</methodResponse>
";
output($xml);
}
function error_message($code, $message) {
$message = htmlspecialchars($message);
$xml = "<methodResponse>
<fault>
<value>
<struct>
<member>
<name>faultCode</name>
<value><int>{$code}</int></value>
</member>
<member>
<name>faultString</name>
<value><string>{$message}</string></value>
</member>
</struct>
</value>
</fault>
</methodResponse>
";
output($xml);
}
function output($xml) {
$xml = '<?xml version="1.0" encoding="utf-8"?>' . "\n" . $xml;
$length = strlen($xml);
header('Connection: close');
header('Content-Length: ' . $length);
header('Content-Type: text/xml');
header('Date: ' . gmdate('r'));
echo $xml;
exit;
}
function cdata($parser, $cdata) {
global $current_tag_contents;
$current_tag_contents .= $cdata;
}
function tag_open($parser, $tag, $attr) {
global $current_tag_contents, $current_tag, $array_structs_types, $array_structs, $message_type, $params;
$current_tag_contents = '';
$current_tag = $tag;
switch ($tag) {
case 'methodCall':
case 'methodResponse':
case 'fault':
$message_type = $tag;
break;
/**
* Deal with stacks of arrays and structs
*/
case 'data': // data is to all intents and puposes more interesting than array
$array_structs_types[] = 'array';
$array_structs[] = array();
break;
case 'struct':
$array_structs_types[] = 'struct';
$array_structs[] = array();
break;
}
}
function tag_close($parser, $tag) {
global $current_tag_contents, $current_tag, $array_structs_types, $array_structs, $message_type, $current_struct_name_array, $method_name, $params;
$valueFlag = false;
switch ($tag) {
case 'int':
case 'i4':
$value = (int) trim($current_tag_contents);
$valueFlag = true;
break;
case 'double':
$value = (double) trim($current_tag_contents);
$valueFlag = true;
break;
case 'string':
$value = $current_tag_contents;
$valueFlag = true;
break;
case 'dateTime.iso8601':
$value = getiso(trim($current_tag_contents));
// $value = $iso->getTimestamp();
$valueFlag = true;
break;
case 'value':
// "If no type is indicated, the type is string."
if (trim($current_tag_contents) != '') {
$value = (string)$current_tag_contents;
$valueFlag = true;
}
break;
case 'boolean':
$value = (boolean) trim($current_tag_contents);
$valueFlag = true;
break;
case 'base64':
$value = base64_decode(trim($current_tag_contents));
$valueFlag = true;
break;
/**
* Deal with stacks of arrays and structs
*/
case 'data':
case 'struct':
$value = @array_pop($array_structs);
@array_pop($array_structs_types);
$valueFlag = true;
break;
case 'member':
array_pop($current_struct_name_array);
break;
case 'name':
$current_struct_name_array[] = trim($current_tag_contents);
break;
case 'methodName':
$method_name = trim($current_tag_contents);
break;
}
if ($valueFlag) {
if (count($array_structs) > 0) {
// Add value to struct or array
if ($array_structs_types[count($array_structs_types)-1] == 'struct') {
// Add to struct
$array_structs[count($array_structs)-1][$current_struct_name_array[count($current_struct_name_array) - 1]] = $value;
}else {
// Add to array
$array_structs[count($array_structs)-1][] = $value;
}
}else {
// Just add as a paramater
$params[] = $value;
}
}
$current_tag_contents = '';
}
PHP
1
https://gitee.com/noimagination/emlog5.git
git@gitee.com:noimagination/emlog5.git
noimagination
emlog5
emlog5
master

搜索帮助