mirror of
https://github.com/typecho/typecho.git
synced 2025-03-18 08:59:40 +01:00
finish xmlrpc
This commit is contained in:
parent
7ca696ce90
commit
d72d4ea2ab
@ -2,7 +2,6 @@
|
||||
|
||||
namespace IXR;
|
||||
|
||||
use Typecho\Common;
|
||||
use Typecho\Http\Client as HttpClient;
|
||||
|
||||
/**
|
||||
@ -16,46 +15,13 @@ class Client
|
||||
/** 默认客户端 */
|
||||
private const DEFAULT_USERAGENT = 'Typecho XML-RPC PHP Library';
|
||||
|
||||
/**
|
||||
* 服务端地址
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
private $server;
|
||||
|
||||
/**
|
||||
* 端口名称
|
||||
*
|
||||
* @access private
|
||||
* @var integer
|
||||
*/
|
||||
private $port;
|
||||
|
||||
/**
|
||||
* 路径名称
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
private $path;
|
||||
|
||||
/**
|
||||
* 地址
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
private $url;
|
||||
|
||||
/**
|
||||
* 客户端
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
private $useragent;
|
||||
|
||||
/**
|
||||
* 消息体
|
||||
*
|
||||
@ -66,7 +32,6 @@ class Client
|
||||
/**
|
||||
* 调试开关
|
||||
*
|
||||
* @access private
|
||||
* @var boolean
|
||||
*/
|
||||
private $debug = false;
|
||||
@ -74,10 +39,9 @@ class Client
|
||||
/**
|
||||
* 请求前缀
|
||||
*
|
||||
* @access private
|
||||
* @var string|null
|
||||
*/
|
||||
private $prefix = null;
|
||||
private $prefix;
|
||||
|
||||
/**
|
||||
* @var Error
|
||||
@ -87,56 +51,21 @@ class Client
|
||||
/**
|
||||
* 客户端构造函数
|
||||
*
|
||||
* @access public
|
||||
* @param string $server 服务端地址
|
||||
* @param string|null $path 路径名称
|
||||
* @param integer $port 端口名称
|
||||
* @param string|null $useragent 客户端
|
||||
* @param string $url 服务端地址
|
||||
* @param string|null $prefix
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(
|
||||
string $server,
|
||||
?string $path = null,
|
||||
int $port = 80,
|
||||
string $useragent = self::DEFAULT_USERAGENT,
|
||||
string $url,
|
||||
?string $prefix = null
|
||||
) {
|
||||
if (!$path) {
|
||||
$this->url = $server;
|
||||
|
||||
// Assume we have been given a Url instead
|
||||
$bits = parse_url($server);
|
||||
$this->server = $bits['host'];
|
||||
$this->port = $bits['port'] ?? 80;
|
||||
$this->path = $bits['path'] ?? '/';
|
||||
|
||||
// Make absolutely sure we have a path
|
||||
if (isset($bits['query'])) {
|
||||
$this->path .= '?' . $bits['query'];
|
||||
}
|
||||
} else {
|
||||
$this->url = Common::buildUrl([
|
||||
'scheme' => 'http',
|
||||
'host' => $server,
|
||||
'path' => $path,
|
||||
'port' => $port
|
||||
]);
|
||||
|
||||
$this->server = $server;
|
||||
$this->path = $path;
|
||||
$this->port = $port;
|
||||
}
|
||||
|
||||
$this->url = $url;
|
||||
$this->prefix = $prefix;
|
||||
$this->useragent = $useragent;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置调试模式
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
* @deprecated
|
||||
*/
|
||||
public function setDebug()
|
||||
{
|
||||
@ -147,11 +76,10 @@ class Client
|
||||
* 执行请求
|
||||
*
|
||||
* @param string $method
|
||||
* @param ...$args
|
||||
* @param array $args
|
||||
* @return bool
|
||||
* @throws HttpClient\Exception
|
||||
*/
|
||||
private function rpcCall(string $method, ...$args): bool
|
||||
private function rpcCall(string $method, array $args): bool
|
||||
{
|
||||
$request = new Request($method, $args);
|
||||
$xml = $request->getXml();
|
||||
@ -162,10 +90,15 @@ class Client
|
||||
return false;
|
||||
}
|
||||
|
||||
$client->setHeader('Content-Type', 'text/xml')
|
||||
->setHeader('User-Agent', $this->useragent)
|
||||
->setData($xml)
|
||||
->send($this->url);
|
||||
try {
|
||||
$client->setHeader('Content-Type', 'text/xml')
|
||||
->setHeader('User-Agent', self::DEFAULT_USERAGENT)
|
||||
->setData($xml)
|
||||
->send($this->url);
|
||||
} catch (HttpClient\Exception $e) {
|
||||
$this->error = new Error(-32700, $e->getMessage());
|
||||
return false;
|
||||
}
|
||||
|
||||
$contents = $client->getResponseBody();
|
||||
|
||||
@ -197,13 +130,12 @@ class Client
|
||||
* $rpc->metaWeblog->newPost();
|
||||
* </code>
|
||||
*
|
||||
* @access public
|
||||
* @param string $prefix 前缀
|
||||
* @return Client
|
||||
*/
|
||||
public function __get(string $prefix): Client
|
||||
{
|
||||
return new self($this->server, $this->path, $this->port, $this->useragent, $this->prefix . $prefix . '.');
|
||||
return new self($this->url, $this->prefix . $prefix . '.');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -215,8 +147,7 @@ class Client
|
||||
*/
|
||||
public function __call($method, $args)
|
||||
{
|
||||
array_unshift($args, $this->prefix . $method);
|
||||
$return = call_user_func_array([$this, 'rpcCall'], $args);
|
||||
$return = $this->rpcCall($this->prefix . $method, $args);
|
||||
|
||||
if ($return) {
|
||||
return $this->getResponse();
|
||||
|
25
var/IXR/Hook.php
Normal file
25
var/IXR/Hook.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace IXR;
|
||||
|
||||
use ReflectionMethod;
|
||||
|
||||
/**
|
||||
* hook rpc call
|
||||
*/
|
||||
interface Hook
|
||||
{
|
||||
/**
|
||||
* @param string $methodName
|
||||
* @param ReflectionMethod $reflectionMethod
|
||||
* @param array $parameters
|
||||
* @return mixed
|
||||
*/
|
||||
public function beforeRpcCall(string $methodName, ReflectionMethod $reflectionMethod, array $parameters);
|
||||
|
||||
/**
|
||||
* @param string $methodName
|
||||
* @param mixed $result
|
||||
*/
|
||||
public function afterRpcCall(string $methodName, &$result): void;
|
||||
}
|
@ -19,11 +19,15 @@ class Server
|
||||
/**
|
||||
* 默认参数
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
private $capabilities;
|
||||
|
||||
/**
|
||||
* @var Hook
|
||||
*/
|
||||
private $hook;
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*
|
||||
@ -91,6 +95,14 @@ class Server
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Hook $hook
|
||||
*/
|
||||
public function setHook(Hook $hook)
|
||||
{
|
||||
$this->hook = $hook;
|
||||
}
|
||||
|
||||
/**
|
||||
* 呼叫内部方法
|
||||
*
|
||||
@ -119,7 +131,7 @@ class Server
|
||||
$requiredArgs = $ref->getNumberOfRequiredParameters();
|
||||
if (count($args) < $requiredArgs) {
|
||||
return new Error(
|
||||
-32601,
|
||||
-32602,
|
||||
'server error. requested class method "' . $methodName . '" require ' . $requiredArgs . ' params.'
|
||||
);
|
||||
}
|
||||
@ -127,20 +139,39 @@ class Server
|
||||
foreach ($ref->getParameters() as $key => $parameter) {
|
||||
if ($parameter->hasType() && !settype($args[$key], $parameter->getType()->getName())) {
|
||||
return new Error(
|
||||
-32601,
|
||||
-32602,
|
||||
'server error. requested class method "'
|
||||
. $methodName . '" ' . $key . ' param has wrong type.'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($this->hook)) {
|
||||
$result = $this->hook->beforeRpcCall($methodName, $ref, $args);
|
||||
|
||||
if (isset($result)) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
$result = call_user_func_array($method, $args);
|
||||
|
||||
if (isset($this->hook)) {
|
||||
$this->hook->afterRpcCall($methodName, $result);
|
||||
}
|
||||
|
||||
return $result;
|
||||
} catch (\ReflectionException $e) {
|
||||
return new Error(
|
||||
-32601,
|
||||
'server error. requested class method "' . $methodName . '" does not exist.'
|
||||
);
|
||||
} catch (\Exception $e) {
|
||||
return new Error(
|
||||
-32001,
|
||||
'server error. requested class method "' . $methodName . '" failed.'
|
||||
);
|
||||
}
|
||||
|
||||
return call_user_func_array($method, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -148,8 +148,7 @@ class Request
|
||||
{
|
||||
$result = $this->get($key, []);
|
||||
|
||||
return is_array($result) ? $result
|
||||
: (strlen($result) > 0 ? [$result] : []);
|
||||
return is_array($result) ? $result : [$result];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -58,7 +58,6 @@ abstract class Widget
|
||||
/**
|
||||
* 队列长度
|
||||
*
|
||||
* @access public
|
||||
* @var integer
|
||||
*/
|
||||
protected $length = 0;
|
||||
@ -80,8 +79,6 @@ abstract class Widget
|
||||
/**
|
||||
* 构造函数,初始化组件
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param WidgetRequest $request request对象
|
||||
* @param WidgetResponse $response response对象
|
||||
* @param mixed $params 参数列表
|
||||
@ -99,10 +96,6 @@ abstract class Widget
|
||||
*
|
||||
* @param string $widgetClass
|
||||
* @param string $aliasClass
|
||||
*
|
||||
* @static
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public static function alias(string $widgetClass, string $aliasClass)
|
||||
{
|
||||
@ -201,6 +194,9 @@ abstract class Widget
|
||||
$alias = static::class;
|
||||
} elseif (Common::nativeClassName(static::class) != 'Typecho_Widget') {
|
||||
$alias = static::class . '@' . $alias;
|
||||
} else {
|
||||
self::$widgetPool = [];
|
||||
return;
|
||||
}
|
||||
|
||||
if (isset(self::$widgetPool[$alias])) {
|
||||
@ -210,9 +206,6 @@ abstract class Widget
|
||||
|
||||
/**
|
||||
* execute function.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
@ -238,7 +231,6 @@ abstract class Widget
|
||||
* 将类本身赋值
|
||||
*
|
||||
* @param mixed $variable 变量名
|
||||
*
|
||||
* @return Widget
|
||||
*/
|
||||
public function to(&$variable): Widget
|
||||
@ -250,15 +242,15 @@ abstract class Widget
|
||||
* 格式化解析堆栈内的所有数据
|
||||
*
|
||||
* @param string $format 数据格式
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function parse(string $format)
|
||||
{
|
||||
while ($this->next()) {
|
||||
echo preg_replace_callback(
|
||||
"/\{([_a-z0-9]+)\}/i",
|
||||
[$this, '__parseCallback'],
|
||||
function (array $matches) {
|
||||
return $this->{$matches[1]};
|
||||
},
|
||||
$format
|
||||
);
|
||||
}
|
||||
@ -306,7 +298,6 @@ abstract class Widget
|
||||
* 根据余数输出
|
||||
*
|
||||
* @param mixed ...$args
|
||||
* @return void
|
||||
*/
|
||||
public function alt(...$args)
|
||||
{
|
||||
@ -328,12 +319,8 @@ abstract class Widget
|
||||
/**
|
||||
* 魔术函数,用于挂接其它函数
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param string $name 函数名
|
||||
* @param array $args 函数参数
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __call(string $name, array $args)
|
||||
{
|
||||
@ -348,10 +335,7 @@ abstract class Widget
|
||||
/**
|
||||
* 获取对象插件句柄
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param string|null $handle 句柄
|
||||
*
|
||||
* @return Plugin
|
||||
*/
|
||||
public function pluginHandle(?string $handle = null): Plugin
|
||||
@ -362,10 +346,7 @@ abstract class Widget
|
||||
/**
|
||||
* 魔术函数,用于获取内部变量
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param string $name 变量名
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function __get(string $name)
|
||||
@ -393,8 +374,6 @@ abstract class Widget
|
||||
*
|
||||
* @param string $name 值对应的键值
|
||||
* @param mixed $value 相应的值
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __set(string $name, $value)
|
||||
{
|
||||
@ -404,10 +383,7 @@ abstract class Widget
|
||||
/**
|
||||
* 验证堆栈值是否存在
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function __isSet(string $name)
|
||||
@ -434,17 +410,4 @@ abstract class Widget
|
||||
{
|
||||
return $this->length;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析回调
|
||||
*
|
||||
* @param array $matches
|
||||
*
|
||||
* @access protected
|
||||
* @return string
|
||||
*/
|
||||
protected function __parseCallback(array $matches): string
|
||||
{
|
||||
return $this->{$matches[1]};
|
||||
}
|
||||
}
|
||||
|
@ -89,7 +89,7 @@ class Comments extends Base
|
||||
if ($updateComment) {
|
||||
$cid = $updateComment->cid;
|
||||
} else {
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** 构建插入结构 */
|
||||
@ -142,7 +142,7 @@ class Comments extends Base
|
||||
if ($deleteComment) {
|
||||
$cid = $deleteComment->cid;
|
||||
} else {
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** 删除评论数据 */
|
||||
@ -328,6 +328,15 @@ class Comments extends Base
|
||||
return $this->parentContent['title'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function ___url(): string
|
||||
{
|
||||
return $this->___permalink();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前评论链接
|
||||
*
|
||||
|
@ -155,7 +155,7 @@ class Contents extends Base
|
||||
{
|
||||
/** 首先验证写入权限 */
|
||||
if (!$this->isWriteable(clone $condition)) {
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** 构建更新结构 */
|
||||
@ -496,7 +496,7 @@ class Contents extends Base
|
||||
$value['pathinfo'] = $routeExists ? Router::url($type, $value) : '#';
|
||||
|
||||
/** 生成静态链接 */
|
||||
$value['permalink'] = Common::url($value['pathinfo'], $this->options->index);
|
||||
$value['url'] = $value['permalink'] = Common::url($value['pathinfo'], $this->options->index);
|
||||
|
||||
/** 处理附件 */
|
||||
if ('attachment' == $type) {
|
||||
|
@ -60,7 +60,7 @@ class Metas extends Base
|
||||
$tmpSlug = $value['slug'];
|
||||
$value['slug'] = urlencode($value['slug']);
|
||||
|
||||
$value['permalink'] = $routeExists ? Router::url($type, $value, $this->options->index) : '#';
|
||||
$value['url'] = $value['permalink'] = $routeExists ? Router::url($type, $value, $this->options->index) : '#';
|
||||
|
||||
/** 生成聚合链接 */
|
||||
/** RSS 2.0 */
|
||||
|
@ -112,7 +112,7 @@ class Users extends Base
|
||||
//生成静态链接
|
||||
$routeExists = (null != Router::get('author'));
|
||||
|
||||
$value['permalink'] = $routeExists ? Router::url('author', $value, $this->options->index) : '#';
|
||||
$value['url'] = $value['permalink'] = $routeExists ? Router::url('author', $value, $this->options->index) : '#';
|
||||
|
||||
/** 生成聚合链接 */
|
||||
/** RSS 2.0 */
|
||||
|
@ -146,9 +146,10 @@ class Edit extends Comments implements ActionInterface
|
||||
/**
|
||||
* 删除评论
|
||||
*
|
||||
* @return int
|
||||
* @throws Exception
|
||||
*/
|
||||
public function deleteComment()
|
||||
public function deleteComment(): int
|
||||
{
|
||||
$comments = $this->request->filter('int')->getArray('coid');
|
||||
$deleteRows = 0;
|
||||
@ -199,6 +200,8 @@ class Edit extends Comments implements ActionInterface
|
||||
/** 返回原网页 */
|
||||
$this->response->goBack();
|
||||
}
|
||||
|
||||
return $deleteRows;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -256,9 +259,10 @@ class Edit extends Comments implements ActionInterface
|
||||
/**
|
||||
* 编辑评论
|
||||
*
|
||||
* @return bool
|
||||
* @throws Exception
|
||||
*/
|
||||
public function editComment()
|
||||
public function editComment(): bool
|
||||
{
|
||||
$coid = $this->request->filter('int')->coid;
|
||||
$commentSelect = $this->db->fetchRow($this->select()
|
||||
@ -270,6 +274,10 @@ class Edit extends Comments implements ActionInterface
|
||||
$comment['mail'] = $this->request->filter('strip_tags', 'trim', 'xss')->mail;
|
||||
$comment['url'] = $this->request->filter('url')->url;
|
||||
|
||||
if ($this->request->is('created')) {
|
||||
$comment['created'] = $this->request->filter('int')->created;
|
||||
}
|
||||
|
||||
/** 评论插件接口 */
|
||||
$this->pluginHandle()->edit($comment, $this);
|
||||
|
||||
@ -287,12 +295,16 @@ class Edit extends Comments implements ActionInterface
|
||||
'success' => 1,
|
||||
'comment' => $updatedComment
|
||||
]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
$this->response->throwJson([
|
||||
'success' => 0,
|
||||
'message' => _t('修评论失败')
|
||||
]);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -381,7 +381,7 @@ class Edit extends Contents implements ActionInterface
|
||||
* 发布内容
|
||||
*
|
||||
* @param array $contents 内容结构
|
||||
* @throws DbException
|
||||
* @throws DbException|Exception
|
||||
*/
|
||||
protected function publish(array $contents)
|
||||
{
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user