finish xmlrpc

This commit is contained in:
joyqi 2021-08-31 18:25:49 +08:00
parent 7ca696ce90
commit d72d4ea2ab
12 changed files with 347 additions and 577 deletions

View File

@ -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
View 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;
}

View File

@ -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);
}
/**

View File

@ -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];
}
/**

View File

@ -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]};
}
}

View File

@ -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();
}
/**
* 获取当前评论链接
*

View File

@ -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) {

View File

@ -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 */

View File

@ -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 */

View File

@ -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;
}
/**

View File

@ -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