This commit is contained in:
joyqi 2021-08-30 17:45:18 +08:00
parent e15c2966a9
commit e2ca6a1fa7
6 changed files with 495 additions and 356 deletions

View File

@ -43,16 +43,12 @@ class Value
switch ($this->type) {
case 'boolean':
return '<boolean>' . (($this->data) ? '1' : '0') . '</boolean>';
break;
case 'int':
return '<int>' . $this->data . '</int>';
break;
case 'double':
return '<double>' . $this->data . '</double>';
break;
case 'string':
return '<string>' . htmlspecialchars($this->data) . '</string>';
break;
case 'array':
$return = '<array><data>' . "\n";
foreach ($this->data as $item) {
@ -60,7 +56,6 @@ class Value
}
$return .= '</data></array>';
return $return;
break;
case 'struct':
$return = '<struct>' . "\n";
foreach ($this->data as $name => $value) {
@ -69,11 +64,9 @@ class Value
}
$return .= '</struct>';
return $return;
break;
case 'date':
case 'base64':
return $this->data->getXml();
break;
}
return false;
}

View File

@ -1,14 +1,16 @@
<?php
if (!defined('__TYPECHO_ROOT_DIR__')) exit;
/**
* 评论设置
*
* @category typecho
* @package Widget
* @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org)
* @license GNU General Public License 2.0
* @version $Id$
*/
namespace Widget\Options;
use Typecho\Db\Exception;
use Typecho\Widget\Helper\Form;
use Widget\ActionInterface;
use Widget\Base\Options;
use Widget\Notice;
if (!defined('__TYPECHO_ROOT_DIR__')) {
exit;
}
/**
* 评论设置组件
@ -19,13 +21,12 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit;
* @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org)
* @license GNU General Public License 2.0
*/
class Widget_Options_Discussion extends Widget_Abstract_Options implements Widget_Interface_Do
class Discussion extends Options implements ActionInterface
{
/**
* 执行更新动作
*
* @access public
* @return void
* @throws Exception
*/
public function updateDiscussionSettings()
{
@ -34,13 +35,35 @@ class Widget_Options_Discussion extends Widget_Abstract_Options implements Widge
$this->response->goBack();
}
$settings = $this->request->from('commentDateFormat', 'commentsListSize', 'commentsPageSize', 'commentsPageDisplay', 'commentsAvatar',
'commentsOrder', 'commentsMaxNestingLevels', 'commentsUrlNofollow', 'commentsPostTimeout', 'commentsUniqueIpInterval', 'commentsWhitelist', 'commentsRequireMail', 'commentsAvatarRating',
'commentsPostTimeout', 'commentsPostInterval', 'commentsRequireModeration', 'commentsRequireURL', 'commentsHTMLTagAllowed', 'commentsStopWords', 'commentsIpBlackList');
$settings = $this->request->from(
'commentDateFormat',
'commentsListSize',
'commentsPageSize',
'commentsPageDisplay',
'commentsAvatar',
'commentsOrder',
'commentsMaxNestingLevels',
'commentsUrlNofollow',
'commentsPostTimeout',
'commentsUniqueIpInterval',
'commentsWhitelist',
'commentsRequireMail',
'commentsAvatarRating',
'commentsPostTimeout',
'commentsPostInterval',
'commentsRequireModeration',
'commentsRequireURL',
'commentsHTMLTagAllowed',
'commentsStopWords',
'commentsIpBlackList'
);
$settings['commentsShow'] = $this->request->getArray('commentsShow');
$settings['commentsPost'] = $this->request->getArray('commentsPost');
$settings['commentsShowCommentOnly'] = $this->isEnableByCheckbox($settings['commentsShow'], 'commentsShowCommentOnly');
$settings['commentsShowCommentOnly'] = $this->isEnableByCheckbox(
$settings['commentsShow'],
'commentsShowCommentOnly'
);
$settings['commentsMarkdown'] = $this->isEnableByCheckbox($settings['commentsShow'], 'commentsMarkdown');
$settings['commentsShowUrl'] = $this->isEnableByCheckbox($settings['commentsShow'], 'commentsShowUrl');
$settings['commentsUrlNofollow'] = $this->isEnableByCheckbox($settings['commentsShow'], 'commentsUrlNofollow');
@ -55,14 +78,23 @@ class Widget_Options_Discussion extends Widget_Abstract_Options implements Widge
$settings['commentsAvatarRating'] = in_array($settings['commentsAvatarRating'], ['G', 'PG', 'R', 'X'])
? $settings['commentsAvatarRating'] : 'G';
$settings['commentsRequireModeration'] = $this->isEnableByCheckbox($settings['commentsPost'], 'commentsRequireModeration');
$settings['commentsRequireModeration'] = $this->isEnableByCheckbox(
$settings['commentsPost'],
'commentsRequireModeration'
);
$settings['commentsWhitelist'] = $this->isEnableByCheckbox($settings['commentsPost'], 'commentsWhitelist');
$settings['commentsRequireMail'] = $this->isEnableByCheckbox($settings['commentsPost'], 'commentsRequireMail');
$settings['commentsRequireURL'] = $this->isEnableByCheckbox($settings['commentsPost'], 'commentsRequireURL');
$settings['commentsCheckReferer'] = $this->isEnableByCheckbox($settings['commentsPost'], 'commentsCheckReferer');
$settings['commentsCheckReferer'] = $this->isEnableByCheckbox(
$settings['commentsPost'],
'commentsCheckReferer'
);
$settings['commentsAntiSpam'] = $this->isEnableByCheckbox($settings['commentsPost'], 'commentsAntiSpam');
$settings['commentsAutoClose'] = $this->isEnableByCheckbox($settings['commentsPost'], 'commentsAutoClose');
$settings['commentsPostIntervalEnable'] = $this->isEnableByCheckbox($settings['commentsPost'], 'commentsPostIntervalEnable');
$settings['commentsPostIntervalEnable'] = $this->isEnableByCheckbox(
$settings['commentsPost'],
'commentsPostIntervalEnable'
);
$settings['commentsPostTimeout'] = intval($settings['commentsPostTimeout']) * 24 * 3600;
$settings['commentsPostInterval'] = round($settings['commentsPostInterval'], 1) * 60;
@ -74,32 +106,40 @@ class Widget_Options_Discussion extends Widget_Abstract_Options implements Widge
$this->update(['value' => $value], $this->db->sql()->where('name = ?', $name));
}
self::widget('Widget_Notice')->set(_t("设置已经保存"), 'success');
Notice::alloc()->set(_t("设置已经保存"), 'success');
$this->response->goBack();
}
/**
* 输出表单结构
*
* @access public
* @return Typecho_Widget_Helper_Form
* @return Form
*/
public function form()
public function form(): Form
{
/** 构建表格 */
$form = new Typecho_Widget_Helper_Form($this->security->getIndex('/action/options-discussion'),
Typecho_Widget_Helper_Form::POST_METHOD);
$form = new Form($this->security->getIndex('/action/options-discussion'), Form::POST_METHOD);
/** 评论日期格式 */
$commentDateFormat = new Typecho_Widget_Helper_Form_Element_Text('commentDateFormat', null, $this->options->commentDateFormat,
_t('评论日期格式'), _t('这是一个默认的格式,当你在模板中调用显示评论日期方法时, 如果没有指定日期格式, 将按照此格式输出.') . '<br />'
. _t('具体写法请参考 <a href="http://www.php.net/manual/zh/function.date.php">PHP 日期格式写法</a>.'));
$commentDateFormat = new Form\Element\Text(
'commentDateFormat',
null,
$this->options->commentDateFormat,
_t('评论日期格式'),
_t('这是一个默认的格式,当你在模板中调用显示评论日期方法时, 如果没有指定日期格式, 将按照此格式输出.') . '<br />'
. _t('具体写法请参考 <a href="http://www.php.net/manual/zh/function.date.php">PHP 日期格式写法</a>.')
);
$commentDateFormat->input->setAttribute('class', 'w-40 mono');
$form->addInput($commentDateFormat);
/** 评论列表数目 */
$commentsListSize = new Typecho_Widget_Helper_Form_Element_Text('commentsListSize', null, $this->options->commentsListSize,
_t('评论列表数目'), _t('此数目用于指定显示在侧边栏中的评论列表数目.'));
$commentsListSize = new Form\Element\Text(
'commentsListSize',
null,
$this->options->commentsListSize,
_t('评论列表数目'),
_t('此数目用于指定显示在侧边栏中的评论列表数目.')
);
$commentsListSize->input->setAttribute('class', 'w-20');
$form->addInput($commentsListSize->addRule('isInteger', _t('请填入一个数字')));
@ -159,8 +199,12 @@ class Widget_Options_Discussion extends Widget_Abstract_Options implements Widge
$commentsShowOptionsValue[] = 'commentsThreaded';
}
$commentsShow = new Typecho_Widget_Helper_Form_Element_Checkbox('commentsShow', $commentsShowOptions,
$commentsShowOptionsValue, _t('评论显示'));
$commentsShow = new Form\Element\Checkbox(
'commentsShow',
$commentsShowOptions,
$commentsShowOptionsValue,
_t('评论显示')
);
$form->addInput($commentsShow->multiMode());
/** 评论提交 */
@ -212,12 +256,12 @@ class Widget_Options_Discussion extends Widget_Abstract_Options implements Widge
$commentsPostOptionsValue[] = 'commentsPostIntervalEnable';
}
$commentsPost = new Typecho_Widget_Helper_Form_Element_Checkbox('commentsPost', $commentsPostOptions,
$commentsPost = new Form\Element\Checkbox('commentsPost', $commentsPostOptions,
$commentsPostOptionsValue, _t('评论提交'));
$form->addInput($commentsPost->multiMode());
/** 允许使用的HTML标签和属性 */
$commentsHTMLTagAllowed = new Typecho_Widget_Helper_Form_Element_Textarea('commentsHTMLTagAllowed', null,
$commentsHTMLTagAllowed = new Form\Element\Textarea('commentsHTMLTagAllowed', null,
$this->options->commentsHTMLTagAllowed,
_t('允许使用的HTML标签和属性'), _t('默认的用户评论不允许填写任何的HTML标签, 你可以在这里填写允许使用的HTML标签.') . '<br />'
. _t('比如: %s', '<code>&lt;a href=&quot;&quot;&gt; &lt;img src=&quot;&quot;&gt; &lt;blockquote&gt;</code>'));
@ -225,7 +269,7 @@ class Widget_Options_Discussion extends Widget_Abstract_Options implements Widge
$form->addInput($commentsHTMLTagAllowed);
/** 提交按钮 */
$submit = new Typecho_Widget_Helper_Form_Element_Submit('submit', null, _t('保存设置'));
$submit = new Form\Element\Submit('submit', null, _t('保存设置'));
$submit->input->setAttribute('class', 'btn primary');
$form->addItem($submit);

View File

@ -1,14 +1,17 @@
<?php
if (!defined('__TYPECHO_ROOT_DIR__')) exit;
/**
* 基本设置
*
* @category typecho
* @package Widget
* @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org)
* @license GNU General Public License 2.0
* @version $Id$
*/
namespace Widget\Options;
use Typecho\Db\Exception;
use Typecho\I18n\GetText;
use Typecho\Widget\Helper\Form;
use Widget\ActionInterface;
use Widget\Base\Options;
use Widget\Notice;
if (!defined('__TYPECHO_ROOT_DIR__')) {
exit;
}
/**
* 基本设置组件
@ -19,16 +22,15 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit;
* @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org)
* @license GNU General Public License 2.0
*/
class Widget_Options_General extends Widget_Abstract_Options implements Widget_Interface_Do
class General extends Options implements ActionInterface
{
/**
* 检查是否在语言列表中
*
* @param mixed $lang
* @access public
* @param string $lang
* @return bool
*/
public function checkLang($lang)
public function checkLang(string $lang): bool
{
$langs = self::getLangs();
return isset($langs[$lang]);
@ -37,10 +39,9 @@ class Widget_Options_General extends Widget_Abstract_Options implements Widget_I
/**
* 获取语言列表
*
* @access private
* @return array
*/
public static function getLangs()
public static function getLangs(): array
{
$dir = defined('__TYPECHO_LANG_DIR__') ? __TYPECHO_LANG_DIR__ : __TYPECHO_ROOT_DIR__ . '/usr/langs';
$files = glob($dir . '/*.mo');
@ -48,7 +49,7 @@ class Widget_Options_General extends Widget_Abstract_Options implements Widget_I
if (!empty($files)) {
foreach ($files as $file) {
$getText = new Typecho_I18n_GetText($file, false);
$getText = new GetText($file, false);
[$name] = explode('.', basename($file));
$title = $getText->translate('lang', $count);
$langs[$name] = $count > - 1 ? $title : $name;
@ -66,7 +67,7 @@ class Widget_Options_General extends Widget_Abstract_Options implements Widget_I
* @param string $ext
* @return boolean
*/
public function removeShell($ext)
public function removeShell(string $ext): bool
{
return !preg_match("/^(php|php4|php5|sh|asp|jsp|rb|py|pl|dll|exe|bat)$/i", $ext);
}
@ -74,8 +75,7 @@ class Widget_Options_General extends Widget_Abstract_Options implements Widget_I
/**
* 执行更新动作
*
* @access public
* @return void
* @throws Exception
*/
public function updateGeneralSettings()
{
@ -84,7 +84,15 @@ class Widget_Options_General extends Widget_Abstract_Options implements Widget_I
$this->response->goBack();
}
$settings = $this->request->from('title', 'description', 'keywords', 'allowRegister', 'allowXmlRpc', 'lang', 'timezone');
$settings = $this->request->from(
'title',
'description',
'keywords',
'allowRegister',
'allowXmlRpc',
'lang',
'timezone'
);
$settings['attachmentTypes'] = $this->request->getArray('attachmentTypes');
if (!defined('__TYPECHO_SITE_URL__')) {
@ -106,8 +114,10 @@ class Widget_Options_General extends Widget_Abstract_Options implements Widget_I
$attachmentTypesOther = $this->request->filter('trim', 'strtolower')->attachmentTypesOther;
if ($this->isEnableByCheckbox($settings['attachmentTypes'], '@other@') && !empty($attachmentTypesOther)) {
$types = implode(',', array_filter(array_map('trim',
explode(',', $attachmentTypesOther)), [$this, 'removeShell']));
$types = implode(
',',
array_filter(array_map('trim', explode(',', $attachmentTypesOther)), [$this, 'removeShell'])
);
if (!empty($types)) {
$attachmentTypes[] = $types;
@ -119,53 +129,79 @@ class Widget_Options_General extends Widget_Abstract_Options implements Widget_I
$this->update(['value' => $value], $this->db->sql()->where('name = ?', $name));
}
self::widget('Widget_Notice')->set(_t("设置已经保存"), 'success');
Notice::alloc()->set(_t("设置已经保存"), 'success');
$this->response->goBack();
}
/**
* 输出表单结构
*
* @access public
* @return Typecho_Widget_Helper_Form
* @return Form
*/
public function form()
public function form(): Form
{
/** 构建表格 */
$form = new Typecho_Widget_Helper_Form($this->security->getIndex('/action/options-general'),
Typecho_Widget_Helper_Form::POST_METHOD);
$form = new Form($this->security->getIndex('/action/options-general'), Form::POST_METHOD);
/** 站点名称 */
$title = new Typecho_Widget_Helper_Form_Element_Text('title', null, $this->options->title, _t('站点名称'), _t('站点的名称将显示在网页的标题处.'));
$title = new Form\Element\Text('title', null, $this->options->title, _t('站点名称'), _t('站点的名称将显示在网页的标题处.'));
$title->input->setAttribute('class', 'w-100');
$form->addInput($title->addRule('required', _t('请填写站点名称'))
->addRule('xssCheck', _t('请不要在站点名称中使用特殊字符')));
/** 站点地址 */
if (!defined('__TYPECHO_SITE_URL__')) {
$siteUrl = new Typecho_Widget_Helper_Form_Element_Text('siteUrl', null, $this->options->originalSiteUrl, _t('站点地址'), _t('站点地址主要用于生成内容的永久链接.') . ($this->options->originalSiteUrl == $this->options->rootUrl ?
'' : '</p><p class="message notice mono">' . _t('当前地址 <strong>%s</strong> 与上述设定值不一致',
$this->options->rootUrl)));
$siteUrl = new Form\Element\Text(
'siteUrl',
null,
$this->options->originalSiteUrl,
_t('站点地址'),
_t('站点地址主要用于生成内容的永久链接.') . ($this->options->originalSiteUrl == $this->options->rootUrl ?
'' : '</p><p class="message notice mono">'
. _t('当前地址 <strong>%s</strong> 与上述设定值不一致', $this->options->rootUrl))
);
$siteUrl->input->setAttribute('class', 'w-100 mono');
$form->addInput($siteUrl->addRule('required', _t('请填写站点地址'))
->addRule('url', _t('请填写一个合法的URL地址')));
}
/** 站点描述 */
$description = new Typecho_Widget_Helper_Form_Element_Text('description', null, $this->options->description, _t('站点描述'), _t('站点描述将显示在网页代码的头部.'));
$description = new Form\Element\Text(
'description',
null,
$this->options->description,
_t('站点描述'),
_t('站点描述将显示在网页代码的头部.')
);
$form->addInput($description->addRule('xssCheck', _t('请不要在站点描述中使用特殊字符')));
/** 关键词 */
$keywords = new Typecho_Widget_Helper_Form_Element_Text('keywords', null, $this->options->keywords, _t('关键词'), _t('请以半角逗号 "," 分割多个关键字.'));
$keywords = new Form\Element\Text(
'keywords',
null,
$this->options->keywords,
_t('关键词'),
_t('请以半角逗号 "," 分割多个关键字.')
);
$form->addInput($keywords->addRule('xssCheck', _t('请不要在关键词中使用特殊字符')));
/** 注册 */
$allowRegister = new Typecho_Widget_Helper_Form_Element_Radio('allowRegister', ['0' => _t('不允许'), '1' => _t('允许')], $this->options->allowRegister, _t('是否允许注册'),
_t('允许访问者注册到你的网站, 默认的注册用户不享有任何写入权限.'));
$allowRegister = new Form\Element\Radio(
'allowRegister',
['0' => _t('不允许'), '1' => _t('允许')],
$this->options->allowRegister,
_t('是否允许注册'),
_t('允许访问者注册到你的网站, 默认的注册用户不享有任何写入权限.')
);
$form->addInput($allowRegister);
/** XMLRPC */
$allowXmlRpc = new Typecho_Widget_Helper_Form_Element_Radio('allowXmlRpc', ['0' => _t('关闭'), '1' => _t('仅关闭 Pingback 接口'), '2' => _t('打开')], $this->options->allowXmlRpc, _t('XMLRPC 接口'));
$allowXmlRpc = new Form\Element\Radio(
'allowXmlRpc',
['0' => _t('关闭'), '1' => _t('仅关闭 Pingback 接口'), '2' => _t('打开')],
$this->options->allowXmlRpc,
_t('XMLRPC 接口')
);
$form->addInput($allowXmlRpc);
/** 语言项 */
@ -175,7 +211,7 @@ class Widget_Options_General extends Widget_Abstract_Options implements Widget_I
$langs = self::getLangs();
if (count($langs) > 1) {
$lang = new Typecho_Widget_Helper_Form_Element_Select('lang', $langs, $this->options->lang, _t('语言'));
$lang = new Form\Element\Select('lang', $langs, $this->options->lang, _t('语言'));
$form->addInput($lang->addRule([$this, 'checkLang'], _t('所选择的语言包不存在')));
}
@ -208,7 +244,7 @@ class Widget_Options_General extends Widget_Abstract_Options implements Widget_I
"-43200" => _t('艾尼威托克岛 (GMT -12)')
];
$timezone = new Typecho_Widget_Helper_Form_Element_Select('timezone', $timezoneList, $this->options->timezone, _t('时区'));
$timezone = new Form\Element\Select('timezone', $timezoneList, $this->options->timezone, _t('时区'));
$form->addInput($timezone);
/** 扩展名 */
@ -239,15 +275,24 @@ class Widget_Options_General extends Widget_Abstract_Options implements Widget_I
'@image@' => _t('图片文件') . ' <code>(gif jpg jpeg png tiff bmp)</code>',
'@media@' => _t('多媒体文件') . ' <code>(mp3 mp4 mov wmv wma rmvb rm avi flv ogg oga ogv)</code>',
'@doc@' => _t('常用档案文件') . ' <code>(txt doc docx xls xlsx ppt pptx zip rar pdf)</code>',
'@other@' => _t('其他格式 %s', ' <input type="text" class="w-50 text-s mono" name="attachmentTypesOther" value="' . htmlspecialchars($attachmentTypesOtherValue) . '" />'),
'@other@' => _t(
'其他格式 %s',
' <input type="text" class="w-50 text-s mono" name="attachmentTypesOther" value="'
. htmlspecialchars($attachmentTypesOtherValue) . '" />'
),
];
$attachmentTypes = new Typecho_Widget_Helper_Form_Element_Checkbox('attachmentTypes', $attachmentTypesOptions,
$attachmentTypesOptionsValue, _t('允许上传的文件类型'), _t('用逗号 "," 将后缀名隔开, 例如: %s', '<code>cpp, h, mak</code>'));
$attachmentTypes = new Form\Element\Checkbox(
'attachmentTypes',
$attachmentTypesOptions,
$attachmentTypesOptionsValue,
_t('允许上传的文件类型'),
_t('用逗号 "," 将后缀名隔开, 例如: %s', '<code>cpp, h, mak</code>')
);
$form->addInput($attachmentTypes->multiMode());
/** 提交按钮 */
$submit = new Typecho_Widget_Helper_Form_Element_Submit('submit', null, _t('保存设置'));
$submit = new Form\Element\Submit('submit', null, _t('保存设置'));
$submit->input->setAttribute('class', 'btn primary');
$form->addItem($submit);
@ -256,9 +301,6 @@ class Widget_Options_General extends Widget_Abstract_Options implements Widget_I
/**
* 绑定动作
*
* @access public
* @return void
*/
public function action()
{

View File

@ -1,14 +1,20 @@
<?php
if (!defined('__TYPECHO_ROOT_DIR__')) exit;
/**
* 基本设置
*
* @category typecho
* @package Widget
* @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org)
* @license GNU General Public License 2.0
* @version $Id$
*/
namespace Widget\Options;
use Typecho\Common;
use Typecho\Cookie;
use Typecho\Db\Exception;
use Typecho\Http\Client;
use Typecho\Router\Parser;
use Typecho\Widget\Helper\Form;
use Widget\ActionInterface;
use Widget\Base\Options;
use Widget\Notice;
if (!defined('__TYPECHO_ROOT_DIR__')) {
exit;
}
/**
* 基本设置组件
@ -19,16 +25,15 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit;
* @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org)
* @license GNU General Public License 2.0
*/
class Widget_Options_Permalink extends Widget_Abstract_Options implements Widget_Interface_Do
class Permalink extends Options implements ActionInterface
{
/**
* 检查pagePattern里是否含有必要参数
*
* @param mixed $value
* @access public
* @return void
* @return bool
*/
public function checkPagePattern($value)
public function checkPagePattern($value): bool
{
return strpos($value, '{slug}') !== false || strpos($value, '{cid}') !== false;
}
@ -37,32 +42,31 @@ class Widget_Options_Permalink extends Widget_Abstract_Options implements Widget
* 检查categoryPattern里是否含有必要参数
*
* @param mixed $value
* @access public
* @return void
* @return bool
*/
public function checkCategoryPattern($value)
public function checkCategoryPattern($value): bool
{
return strpos($value, '{slug}') !== false || strpos($value, '{mid}') !== false || strpos($value, '{directory}') !== false;
return strpos($value, '{slug}') !== false
|| strpos($value, '{mid}') !== false
|| strpos($value, '{directory}') !== false;
}
/**
* 检测是否可以rewrite
*
* @access public
* @param string $value 是否打开rewrite
* @return void
* @return bool
*/
public function checkRewrite($value)
public function checkRewrite(string $value)
{
if ($value) {
$this->user->pass('administrator');
/** 首先直接请求远程地址验证 */
$client = Typecho_Http_Client::get();
$client = Client::get();
$hasWrote = false;
if (!file_exists(__TYPECHO_ROOT_DIR__ . '/.htaccess')
&& strpos(php_sapi_name(), 'apache') !== false) {
if (!file_exists(__TYPECHO_ROOT_DIR__ . '/.htaccess') && strpos(php_sapi_name(), 'apache') !== false) {
if (is_writeable(__TYPECHO_ROOT_DIR__)) {
$parsed = parse_url($this->options->siteUrl);
$basePath = empty($parsed['path']) ? '/' : $parsed['path'];
@ -83,7 +87,7 @@ RewriteRule ^(.*)$ {$basePath}index.php/$1 [L]
/** 发送一个rewrite地址请求 */
$client->setData(['do' => 'remoteCallback'])
->setHeader('User-Agent', $this->options->generator)
->send(Typecho_Common::url('/action/ajax', $this->options->siteUrl));
->send(Common::url('/action/ajax', $this->options->siteUrl));
if (200 == $client->getResponseStatus() && 'OK' == $client->getResponseBody()) {
return true;
@ -103,13 +107,13 @@ RewriteRule . {$basePath}index.php [L]
</IfModule>");
//再次进行验证
$client = Typecho_Http_Client::get();
$client = Client::get();
if ($client) {
/** 发送一个rewrite地址请求 */
$client->setData(['do' => 'remoteCallback'])
->setHeader('User-Agent', $this->options->generator)
->send(Typecho_Common::url('/action/ajax', $this->options->siteUrl));
->send(Common::url('/action/ajax', $this->options->siteUrl));
if (200 == $client->getResponseStatus() && 'OK' == $client->getResponseBody()) {
return true;
@ -118,8 +122,8 @@ RewriteRule . {$basePath}index.php [L]
unlink(__TYPECHO_ROOT_DIR__ . '/.htaccess');
}
} catch (Typecho_Http_Client_Exception $e) {
if (false !== $hasWrote) {
} catch (Client\Exception $e) {
if (false != $hasWrote) {
@unlink(__TYPECHO_ROOT_DIR__ . '/.htaccess');
}
return false;
@ -136,14 +140,13 @@ RewriteRule . {$basePath}index.php [L]
/**
* 执行更新动作
*
* @access public
* @return void
* @throws Exception
*/
public function updatePermalinkSettings()
{
/** 验证格式 */
if ($this->form()->validate()) {
Typecho_Cookie::set('__typecho_form_item_postPattern', $this->request->customPattern);
Cookie::set('__typecho_form_item_postPattern', $this->request->customPattern);
$this->response->goBack();
}
@ -174,9 +177,9 @@ RewriteRule . {$basePath}index.php [L]
}
if ($patternValid) {
self::widget('Widget_Notice')->set(_t("设置已经保存"), 'success');
Notice::alloc()->set(_t("设置已经保存"), 'success');
} else {
self::widget('Widget_Notice')->set(_t("自定义链接与现有规则存在冲突! 它可能影响解析效率, 建议你重新分配一个规则."), 'notice');
Notice::alloc()->set(_t("自定义链接与现有规则存在冲突! 它可能影响解析效率, 建议你重新分配一个规则."), 'notice');
}
$this->response->goBack();
}
@ -184,29 +187,34 @@ RewriteRule . {$basePath}index.php [L]
/**
* 输出表单结构
*
* @access public
* @return Typecho_Widget_Helper_Form
* @return Form
*/
public function form()
public function form(): Form
{
/** 构建表格 */
$form = new Typecho_Widget_Helper_Form($this->security->getRootUrl('index.php/action/options-permalink'),
Typecho_Widget_Helper_Form::POST_METHOD);
$form = new Form($this->security->getRootUrl('index.php/action/options-permalink'), Form::POST_METHOD);
if (!defined('__TYPECHO_REWRITE__')) {
/** 是否使用地址重写功能 */
$rewrite = new Typecho_Widget_Helper_Form_Element_Radio('rewrite', ['0' => _t('不启用'), '1' => _t('启用')],
$this->options->rewrite, _t('是否使用地址重写功能'), _t('地址重写即 rewrite 功能是某些服务器软件提供的优化内部连接的功能.') . '<br />'
. _t('打开此功能可以让你的链接看上去完全是静态地址.'));
$rewrite = new Form\Element\Radio(
'rewrite',
['0' => _t('不启用'), '1' => _t('启用')],
$this->options->rewrite,
_t('是否使用地址重写功能'),
_t('地址重写即 rewrite 功能是某些服务器软件提供的优化内部连接的功能.') . '<br />'
. _t('打开此功能可以让你的链接看上去完全是静态地址.')
);
// disable rewrite check when rewrite opened
if (!$this->options->rewrite && !$this->request->is('enableRewriteAnyway=1')) {
$errorStr = _t('重写功能检测失败, 请检查你的服务器设置');
/** 如果是apache服务器, 可能存在无法写入.htaccess文件的现象 */
if (((isset($_SERVER['SERVER_SOFTWARE']) && false !== strpos(strtolower($_SERVER['SERVER_SOFTWARE']), 'apache'))
|| function_exists('apache_get_version')) && !file_exists(__TYPECHO_ROOT_DIR__ . '/.htaccess')
&& !is_writeable(__TYPECHO_ROOT_DIR__)) {
if (
strpos(php_sapi_name(), 'apache') !== false
&& !file_exists(__TYPECHO_ROOT_DIR__ . '/.htaccess')
&& !is_writeable(__TYPECHO_ROOT_DIR__)
) {
$errorStr .= '<br /><strong>' . _t('我们检测到你使用了apache服务器, 但是程序无法在根目录创建.htaccess文件, 这可能是产生这个错误的原因.')
. _t('请调整你的目录权限, 或者手动创建一个.htaccess文件.') . '</strong>';
}
@ -233,35 +241,52 @@ RewriteRule . {$basePath}index.php [L]
$customPatternValue = null;
if (isset($this->request->__typecho_form_item_postPattern)) {
$customPatternValue = $this->request->__typecho_form_item_postPattern;
Typecho_Cookie::delete('__typecho_form_item_postPattern');
Cookie::delete('__typecho_form_item_postPattern');
} elseif (!isset($patterns[$postPatternValue])) {
$customPatternValue = $this->decodeRule($postPatternValue);
}
$patterns['custom'] = _t('个性化定义') . ' <input type="text" class="w-50 text-s mono" name="customPattern" value="' . $customPatternValue . '" />';
$postPattern = new Typecho_Widget_Helper_Form_Element_Radio('postPattern', $patterns,
$postPatternValue, _t('自定义文章路径'), _t('可用参数: <code>{cid}</code> 日志 ID, <code>{slug}</code> 日志缩略名, <code>{category}</code> 分类, <code>{directory}</code> 多级分类, <code>{year}</code> 年, <code>{month}</code> 月, <code>{day}</code> 日')
$postPattern = new Form\Element\Radio(
'postPattern',
$patterns,
$postPatternValue,
_t('自定义文章路径'),
_t('可用参数: <code>{cid}</code> 日志 ID, <code>{slug}</code> 日志缩略名, <code>{category}</code> 分类, <code>{directory}</code> 多级分类, <code>{year}</code> 年, <code>{month}</code> 月, <code>{day}</code> 日')
. '<br />' . _t('选择一种合适的文章静态路径风格, 使得你的网站链接更加友好.')
. '<br />' . _t('一旦你选择了某种链接风格请不要轻易修改它.'));
. '<br />' . _t('一旦你选择了某种链接风格请不要轻易修改它.')
);
if ($customPatternValue) {
$postPattern->value('custom');
}
$form->addInput($postPattern->multiMode());
/** 独立页面后缀名 */
$pagePattern = new Typecho_Widget_Helper_Form_Element_Text('pagePattern', null, $this->decodeRule($this->options->routingTable['page']['url']), _t('独立页面路径'), _t('可用参数: <code>{cid}</code> 页面 ID, <code>{slug}</code> 页面缩略名')
. '<br />' . _t('请在路径中至少包含上述的一项参数.'));
$pagePattern = new Form\Element\Text(
'pagePattern',
null,
$this->decodeRule($this->options->routingTable['page']['url']),
_t('独立页面路径'),
_t('可用参数: <code>{cid}</code> 页面 ID, <code>{slug}</code> 页面缩略名')
. '<br />' . _t('请在路径中至少包含上述的一项参数.')
);
$pagePattern->input->setAttribute('class', 'mono w-60');
$form->addInput($pagePattern->addRule([$this, 'checkPagePattern'], _t('独立页面路径中没有包含 {cid} 或者 {slug} ')));
/** 分类页面 */
$categoryPattern = new Typecho_Widget_Helper_Form_Element_Text('categoryPattern', null, $this->decodeRule($this->options->routingTable['category']['url']), _t('分类路径'), _t('可用参数: <code>{mid}</code> 分类 ID, <code>{slug}</code> 分类缩略名, <code>{directory}</code> 多级分类')
. '<br />' . _t('请在路径中至少包含上述的一项参数.'));
$categoryPattern = new Form\Element\Text(
'categoryPattern',
null,
$this->decodeRule($this->options->routingTable['category']['url']),
_t('分类路径'),
_t('可用参数: <code>{mid}</code> 分类 ID, <code>{slug}</code> 分类缩略名, <code>{directory}</code> 多级分类')
. '<br />' . _t('请在路径中至少包含上述的一项参数.')
);
$categoryPattern->input->setAttribute('class', 'mono w-60');
$form->addInput($categoryPattern->addRule([$this, 'checkCategoryPattern'], _t('分类路径中没有包含 {mid} 或者 {slug} ')));
/** 提交按钮 */
$submit = new Typecho_Widget_Helper_Form_Element_Submit('submit', null, _t('保存设置'));
$submit = new Form\Element\Submit('submit', null, _t('保存设置'));
$submit->input->setAttribute('class', 'btn primary');
$form->addItem($submit);
@ -271,11 +296,10 @@ RewriteRule . {$basePath}index.php [L]
/**
* 解析自定义的路径
*
* @access private
* @param string $rule 待解码的路径
* @return string
*/
protected function decodeRule($rule)
protected function decodeRule(string $rule): string
{
return preg_replace("/\[([_a-z0-9-]+)[^\]]*\]/i", "{\\1}", $rule);
}
@ -283,11 +307,10 @@ RewriteRule . {$basePath}index.php [L]
/**
* 检验规则是否冲突
*
* @access public
* @param string $value 路由规则
* @return boolean
*/
public function checkRule($value)
public function checkRule(string $value): bool
{
if ('custom' != $value) {
return true;
@ -295,15 +318,18 @@ RewriteRule . {$basePath}index.php [L]
$routingTable = $this->options->routingTable;
$currentTable = ['custom' => ['url' => $this->encodeRule($this->request->customPattern)]];
$parser = new Typecho_Router_Parser($currentTable);
$parser = new Parser($currentTable);
$currentTable = $parser->parse();
$regx = $currentTable['custom']['regx'];
foreach ($routingTable as $key => $val) {
if ('post' != $key && 'page' != $key) {
$pathInfo = preg_replace("/\[([_a-z0-9-]+)[^\]]*\]/i", "{\\1}", $val['url']);
$pathInfo = str_replace(['{cid}', '{slug}', '{category}', '{year}', '{month}', '{day}', '{', '}'],
['123', 'hello', 'default', '2008', '08', '08', '', ''], $pathInfo);
$pathInfo = str_replace(
['{cid}', '{slug}', '{category}', '{year}', '{month}', '{day}', '{', '}'],
['123', 'hello', 'default', '2008', '08', '08', '', ''],
$pathInfo
);
if (preg_match($regx, $pathInfo)) {
return false;
@ -317,17 +343,19 @@ RewriteRule . {$basePath}index.php [L]
/**
* 编码自定义的路径
*
* @access private
* @param string $rule 待编码的路径
* @return string
*/
protected function encodeRule($rule)
protected function encodeRule(string $rule): string
{
return str_replace(['{cid}', '{slug}', '{category}', '{directory}', '{year}', '{month}', '{day}', '{mid}'],
return str_replace(
['{cid}', '{slug}', '{category}', '{directory}', '{year}', '{month}', '{day}', '{mid}'],
[
'[cid:digital]', '[slug]', '[category]', '[directory:split:0]',
'[year:digital:4]', '[month:digital:2]', '[day:digital:2]', '[mid:digital]'
], $rule);
],
$rule
);
}
/**

View File

@ -1,14 +1,15 @@
<?php
if (!defined('__TYPECHO_ROOT_DIR__')) exit;
/**
* 文章阅读设置
*
* @category typecho
* @package Widget
* @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org)
* @license GNU General Public License 2.0
* @version $Id$
*/
namespace Widget\Options;
use Typecho\Db\Exception;
use Typecho\Plugin;
use Typecho\Widget\Helper\Form;
use Widget\Notice;
if (!defined('__TYPECHO_ROOT_DIR__')) {
exit;
}
/**
* 文章阅读设置组件
@ -19,13 +20,12 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit;
* @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org)
* @license GNU General Public License 2.0
*/
class Widget_Options_Reading extends Widget_Options_Permalink
class Reading extends Permalink
{
/**
* 执行更新动作
*
* @access public
* @return void
* @throws Exception
*/
public function updateReadingSettings()
{
@ -34,22 +34,29 @@ class Widget_Options_Reading extends Widget_Options_Permalink
$this->response->goBack();
}
$settings = $this->request->from('postDateFormat', 'frontPage', 'frontArchive', 'pageSize', 'postsListSize', 'feedFullText');
$settings = $this->request->from(
'postDateFormat',
'frontPage',
'frontArchive',
'pageSize',
'postsListSize',
'feedFullText'
);
if ('page' == $settings['frontPage'] && isset($this->request->frontPagePage) &&
if (
'page' == $settings['frontPage'] && isset($this->request->frontPagePage) &&
$this->db->fetchRow($this->db->select('cid')
->from('table.contents')->where('type = ?', 'page')
->where('status = ?', 'publish')->where('created < ?', $this->options->time)
->where('cid = ?', $pageId = intval($this->request->frontPagePage)))) {
->where('cid = ?', $pageId = intval($this->request->frontPagePage)))
) {
$settings['frontPage'] = 'page:' . $pageId;
} elseif ('file' == $settings['frontPage'] && isset($this->request->frontPageFile) &&
} elseif (
'file' == $settings['frontPage'] && isset($this->request->frontPageFile) &&
file_exists(__TYPECHO_ROOT_DIR__ . '/' . __TYPECHO_THEME_DIR__ . '/' . $this->options->theme . '/' .
($file = trim($this->request->frontPageFile, " ./\\")))) {
($file = trim($this->request->frontPageFile, " ./\\")))
) {
$settings['frontPage'] = 'file:' . $file;
} else {
$settings['frontPage'] = 'recent';
}
@ -59,7 +66,8 @@ class Widget_Options_Reading extends Widget_Options_Permalink
if ($settings['frontArchive']) {
$routingTable = $this->options->routingTable;
$routingTable['archive']['url'] = '/' . ltrim($this->encodeRule($this->request->archivePattern), '/');
$routingTable['archive_page']['url'] = rtrim($routingTable['archive']['url'], '/') . '/page/[page:digital]/';
$routingTable['archive_page']['url'] = rtrim($routingTable['archive']['url'], '/')
. '/page/[page:digital]/';
if (isset($routingTable[0])) {
unset($routingTable[0]);
@ -75,27 +83,30 @@ class Widget_Options_Reading extends Widget_Options_Permalink
$this->update(['value' => $value], $this->db->sql()->where('name = ?', $name));
}
self::widget('Widget_Notice')->set(_t("设置已经保存"), 'success');
Notice::alloc()->set(_t("设置已经保存"), 'success');
$this->response->goBack();
}
/**
* 输出表单结构
*
* @access public
* @return Typecho_Widget_Helper_Form
* @return Form
*/
public function form()
public function form(): Form
{
/** 构建表格 */
$form = new Typecho_Widget_Helper_Form($this->security->getIndex('/action/options-reading'),
Typecho_Widget_Helper_Form::POST_METHOD);
$form = new Form($this->security->getIndex('/action/options-reading'), Form::POST_METHOD);
/** 文章日期格式 */
$postDateFormat = new Typecho_Widget_Helper_Form_Element_Text('postDateFormat', null, $this->options->postDateFormat,
_t('文章日期格式'), _t('此格式用于指定显示在文章归档中的日期默认显示格式.') . '<br />'
$postDateFormat = new Form\Element\Text(
'postDateFormat',
null,
$this->options->postDateFormat,
_t('文章日期格式'),
_t('此格式用于指定显示在文章归档中的日期默认显示格式.') . '<br />'
. _t('在某些主题中这个格式可能不会生效, 因为主题作者可以自定义日期格式.') . '<br />'
. _t('请参考 <a href="http://www.php.net/manual/zh/function.date.php">PHP 日期格式写法</a>.'));
. _t('请参考 <a href="http://www.php.net/manual/zh/function.date.php">PHP 日期格式写法</a>.')
);
$postDateFormat->input->setAttribute('class', 'w-40 mono');
$form->addInput($postDateFormat->addRule('xssCheck', _t('请不要在日期格式中使用特殊字符')));
@ -133,7 +144,10 @@ class Widget_Options_Reading extends Widget_Options_Permalink
. '>' . $page['title'] . '</option>';
}
$pagesSelect .= '</select>';
$frontPageOptions['page'] = _t('使用 %s 页面作为首页', '</label>' . $pagesSelect . '<label for="frontPage-frontPagePage">');
$frontPageOptions['page'] = _t(
'使用 %s 页面作为首页',
'</label>' . $pagesSelect . '<label for="frontPage-frontPagePage">'
);
$selectedFrontPageType = 'page';
}
@ -142,7 +156,7 @@ class Widget_Options_Reading extends Widget_Options_Permalink
$filesSelect = '';
foreach ($files as $file) {
$info = Typecho_Plugin::parseInfo($file);
$info = Plugin::parseInfo($file);
$file = basename($file);
if ('index.php' != $file && 'index' == $info['title']) {
@ -157,9 +171,11 @@ class Widget_Options_Reading extends Widget_Options_Permalink
}
if (!empty($filesSelect)) {
$frontPageOptions['file'] = _t('直接调用 %s 模板文件',
$frontPageOptions['file'] = _t(
'直接调用 %s 模板文件',
'</label><select name="frontPageFile" id="frontPage-frontPageFile">'
. $filesSelect . '</select><label for="frontPage-frontPageFile">');
. $filesSelect . '</select><label for="frontPage-frontPageFile">'
);
$selectedFrontPageType = 'file';
}
@ -173,30 +189,44 @@ class Widget_Options_Reading extends Widget_Options_Permalink
$frontPageOptions[$selectedFrontPageType] .= $frontPattern;
}
$frontPage = new Typecho_Widget_Helper_Form_Element_Radio('frontPage', $frontPageOptions,
$frontPageType, _t('站点首页'));
$frontPage = new Form\Element\Radio('frontPage', $frontPageOptions, $frontPageType, _t('站点首页'));
$form->addInput($frontPage->multiMode());
/** 文章列表数目 */
$postsListSize = new Typecho_Widget_Helper_Form_Element_Text('postsListSize', null, $this->options->postsListSize,
_t('文章列表数目'), _t('此数目用于指定显示在侧边栏中的文章列表数目.'));
$postsListSize = new Form\Element\Text(
'postsListSize',
null,
$this->options->postsListSize,
_t('文章列表数目'),
_t('此数目用于指定显示在侧边栏中的文章列表数目.')
);
$postsListSize->input->setAttribute('class', 'w-20');
$form->addInput($postsListSize->addRule('isInteger', _t('请填入一个数字')));
/** 每页文章数目 */
$pageSize = new Typecho_Widget_Helper_Form_Element_Text('pageSize', null, $this->options->pageSize,
_t('每页文章数目'), _t('此数目用于指定文章归档输出时每页显示的文章数目.'));
$pageSize = new Form\Element\Text(
'pageSize',
null,
$this->options->pageSize,
_t('每页文章数目'),
_t('此数目用于指定文章归档输出时每页显示的文章数目.')
);
$pageSize->input->setAttribute('class', 'w-20');
$form->addInput($pageSize->addRule('isInteger', _t('请填入一个数字')));
/** FEED全文输出 */
$feedFullText = new Typecho_Widget_Helper_Form_Element_Radio('feedFullText', ['0' => _t('仅输出摘要'), '1' => _t('全文输出')],
$this->options->feedFullText, _t('聚合全文输出'), _t('如果你不希望在聚合中输出文章全文,请使用仅输出摘要选项.') . '<br />'
. _t('摘要的文字取决于你在文章中使用分隔符的位置.'));
$feedFullText = new Form\Element\Radio(
'feedFullText',
['0' => _t('仅输出摘要'), '1' => _t('全文输出')],
$this->options->feedFullText,
_t('聚合全文输出'),
_t('如果你不希望在聚合中输出文章全文,请使用仅输出摘要选项.') . '<br />'
. _t('摘要的文字取决于你在文章中使用分隔符的位置.')
);
$form->addInput($feedFullText);
/** 提交按钮 */
$submit = new Typecho_Widget_Helper_Form_Element_Submit('submit', null, _t('保存设置'));
$submit = new Form\Element\Submit('submit', null, _t('保存设置'));
$submit->input->setAttribute('class', 'btn primary');
$form->addItem($submit);

View File

@ -1,12 +1,19 @@
<?php
if (!defined('__TYPECHO_ROOT_DIR__')) exit;
/**
* Typecho Blog Platform
*
* @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org)
* @license GNU General Public License 2.0
* @version $Id$
*/
namespace Widget;
use IXR\Date;
use IXR\Error;
use IXR\Server;
use Typecho\Common;
use Typecho\Router;
use Typecho\Widget\Exception;
use Widget\Base\Contents;
use Widget\Contents\Page\Admin as PageAdmin;
if (!defined('__TYPECHO_ROOT_DIR__')) {
exit;
}
/**
* XmlRpc接口
@ -17,13 +24,12 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit;
* @copyright Copyright (c) 2008 Typecho team (http://www.typecho.org)
* @license GNU General Public License 2.0
*/
class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface_Do
class XmlRpc extends Contents implements ActionInterface
{
/**
* 当前错误
*
* @access private
* @var IXR_Error
* @var Error
*/
private $error;
@ -33,7 +39,7 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
* @access private
* @var array
*/
private $_wpOptions;
private $wpOptions;
/**
* 已经使用过的组件列表
@ -41,16 +47,14 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
* @access private
* @var array
*/
private $_usedWidgetNameList = [];
private $usedWidgetNameList = [];
/**
* 如果这里没有重载, 每次都会被默认执行
*
* @access public
* @param boolen $run 是否执行
* @return void
* @param bool $run 是否执行
*/
public function execute($run = false)
public function execute(bool $run = false)
{
if ($run) {
parent::execute();
@ -59,7 +63,7 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
// 临时保护模块
$this->security->enable(false);
$this->_wpOptions = [
$this->wpOptions = [
// Read only options
'software_name' => [
'desc' => _t('软件名称'),
@ -140,8 +144,6 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
* @param int $pageId
* @param string $userName
* @param string $password
* @access public
* @return struct $pageStruct
*/
public function wpGetPage($blogId, $pageId, $userName, $password)
{
@ -156,16 +158,16 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
/** widget方法的第三个参数可以指定强行转换传入此widget的request参数 */
/** 此组件会进行复杂的权限检测 */
$page = $this->singletonWidget('Widget_Contents_Page_Edit', null, "cid={$pageId}");
} catch (Typecho_Widget_Exception $e) {
} catch (Exception $e) {
/** 截获可能会抛出的异常(参见 Widget_Contents_Page_Edit 的 execute 方法) */
return new IXR_Error($e->getCode(), $e->getMessage());
return new Error($e->getCode(), $e->getMessage());
}
/** 对文章内容做截取处理以获得description和text_more*/
[$excerpt, $more] = $this->getPostExtended($page);
$pageStruct = [
'dateCreated' => new IXR_Date($this->options->timezone + $page->created),
'dateCreated' => new Date($this->options->timezone + $page->created),
'userid' => $page->authorId,
'page_id' => $page->cid,
'page_status' => $this->typechoToWordpressStatus($page->status, 'page'),
@ -186,7 +188,7 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
'wp_page_order' => $page->order, //meta是描述字段, 在page时表示顺序
'wp_author_id' => $page->authorId,
'wp_author_display_name' => $page->author->screenName,
'date_created_gmt' => new IXR_Date($page->created),
'date_created_gmt' => new Date($page->created),
'custom_fields' => [],
'wp_page_template' => $page->template
];
@ -198,7 +200,7 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
* 检查权限
*
* @access public
* @return void
* @return bool
*/
public function checkAccess($name, $password, $level = 'contributor')
{
@ -208,11 +210,11 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
$this->user->execute();
return true;
} else {
$this->error = new IXR_Error(403, _t('权限不足'));
$this->error = new Error(403, _t('权限不足'));
return false;
}
} else {
$this->error = new IXR_Error(403, _t('无法登陆, 密码错误'));
$this->error = new Error(403, _t('无法登陆, 密码错误'));
return false;
}
}
@ -230,18 +232,17 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
*/
private function singletonWidget($alias, $params = null, $request = null, $enableResponse = true)
{
$this->_usedWidgetNameList[] = $alias;
$this->usedWidgetNameList[] = $alias;
return Typecho_Widget::widget($alias, $params, $request, $enableResponse);
}
/**
* 获取扩展字段
*
* @access private
* @param Widget_Abstract_Contents $content
* @param Contents $content
* @return array
*/
private function getPostExtended(Widget_Abstract_Contents $content)
private function getPostExtended(Contents $content): array
{
//根据客户端显示来判断是否显示html代码
$agent = $this->request->getAgent();
@ -261,20 +262,19 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
$post = explode('<!--more-->', $text, 2);
return [
$this->options->xmlrpcMarkdown ? $post[0] : Typecho_Common::fixHtml($post[0]),
isset($post[1]) ? Typecho_Common::fixHtml($post[1]) : null
$this->options->xmlrpcMarkdown ? $post[0] : Common::fixHtml($post[0]),
isset($post[1]) ? Common::fixHtml($post[1]) : null
];
}
/**
* 将typecho的状态类型转换为wordperss的风格
*
* @access private
* @param string $status typecho的状态
* @param string $type 内容类型
* @return string
*/
private function typechoToWordpressStatus($status, $type = 'post')
private function typechoToWordpressStatus(string $status, string $type = 'post'): string
{
if ('post' == $type) {
/** 文章状态 */
@ -299,13 +299,12 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
}
} elseif ('comment' == $type) {
switch ($status) {
case 'publish':
case 'approved':
return 'approve';
case 'waiting':
return 'hold';
case 'spam':
return $status;
case 'publish':
case 'approved':
default:
return 'approve';
}
@ -320,10 +319,9 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
* @param int $blogId
* @param string $userName
* @param string $password
* @access public
* @return array(contains $pageStruct)
* @return array|Error
*/
public function wpGetPages($blogId, $userName, $password)
public function wpGetPages(int $blogId, string $userName, string $password)
{
if (!$this->checkAccess($userName, $password)) {
return $this->error;
@ -331,7 +329,7 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
/** 过滤type为page的contents */
/** 同样需要flush一下, 需要取出所有status的页面 */
$pages = $this->singletonWidget('Widget_Contents_Page_Admin', null, 'status=all');
$pages = PageAdmin::alloc(null, 'status=all');
/** 初始化要返回的数据结构 */
$pageStructs = [];
@ -340,10 +338,13 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
/** 对文章内容做截取处理以获得description和text_more*/
[$excerpt, $more] = $this->getPostExtended($pages);
$pageStructs[] = [
'dateCreated' => new IXR_Date($this->options->timezone + $pages->created),
'dateCreated' => new Date($this->options->timezone + $pages->created),
'userid' => $pages->authorId,
'page_id' => intval($pages->cid),
'page_status' => $this->typechoToWordpressStatus(($pages->hasSaved || 'page_draft' == $pages->type) ? 'draft' : $pages->status, 'page'),
'page_status' => $this->typechoToWordpressStatus(
($pages->hasSaved || 'page_draft' == $pages->type) ? 'draft' : $pages->status,
'page'
),
'description' => $excerpt,
'title' => $pages->title,
'link' => $pages->permalink,
@ -361,7 +362,7 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
'wp_page_order' => intval($pages->order), //meta是描述字段, 在page时表示顺序
'wp_author_id' => $pages->authorId,
'wp_author_display_name' => $pages->author->screenName,
'date_created_gmt' => new IXR_Date($pages->created),
'date_created_gmt' => new Date($pages->created),
'custom_fields' => [],
'wp_page_template' => $pages->template
];
@ -426,10 +427,10 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
. "\n<!--more-->\n" . $content['mt_text_more'] : $content['description'];
$input['text'] = $this->pluginHandle()->textFilter($input['text'], $this);
$input['password'] = isset($content["wp_password"]) ? $content["wp_password"] : null;
$input['order'] = isset($content["wp_page_order"]) ? $content["wp_page_order"] : null;
$input['password'] = $content["wp_password"] ?? null;
$input['order'] = $content["wp_page_order"] ?? null;
$input['tags'] = isset($content['mt_keywords']) ? $content['mt_keywords'] : null;
$input['tags'] = $content['mt_keywords'] ?? null;
$input['category'] = [];
if (isset($content['postId'])) {
@ -442,13 +443,16 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
if (isset($content['dateCreated'])) {
/** 解决客户端与服务器端时间偏移 */
$input['created'] = $content['dateCreated']->getTimestamp() - $this->options->timezone + $this->options->serverTimezone;
$input['created'] = $content['dateCreated']->getTimestamp()
- $this->options->timezone + $this->options->serverTimezone;
}
if (!empty($content['categories']) && is_array($content['categories'])) {
foreach ($content['categories'] as $category) {
if (!$this->db->fetchRow($this->db->select('mid')
->from('table.metas')->where('type = ? AND name = ?', 'category', $category))) {
if (
!$this->db->fetchRow($this->db->select('mid')
->from('table.metas')->where('type = ? AND name = ?', 'category', $category))
) {
$result = $this->wpNewCategory($blogId, $userName, $password, ['name' => $category]);
if (true !== $result) {
return $result;
@ -462,11 +466,14 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
}
$input['allowComment'] = (isset($content['mt_allow_comments']) && (1 == $content['mt_allow_comments']
|| 'open' == $content['mt_allow_comments'])) ? 1 : ((isset($content['mt_allow_comments']) && (0 == $content['mt_allow_comments']
|| 'closed' == $content['mt_allow_comments'])) ? 0 : $this->options->defaultAllowComment);
|| 'open' == $content['mt_allow_comments']))
? 1 : ((isset($content['mt_allow_comments']) && (0 == $content['mt_allow_comments']
|| 'closed' == $content['mt_allow_comments']))
? 0 : $this->options->defaultAllowComment);
$input['allowPing'] = (isset($content['mt_allow_pings']) && (1 == $content['mt_allow_pings']
|| 'open' == $content['mt_allow_pings'])) ? 1 : ((isset($content['mt_allow_pings']) && (0 == $content['mt_allow_pings']
|| 'open' == $content['mt_allow_pings']))
? 1 : ((isset($content['mt_allow_pings']) && (0 == $content['mt_allow_pings']
|| 'closed' == $content['mt_allow_pings'])) ? 0 : $this->options->defaultAllowPing);
$input['allowFeed'] = $this->options->defaultAllowFeed;
@ -514,8 +521,8 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
}
return $this->singletonWidget('Widget_Notice')->getHighlightId();
} catch (Typecho_Widget_Exception $e) {
return new IXR_Error($e->getCode(), $e->getMessage());
} catch (Exception $e) {
return new Error($e->getCode(), $e->getMessage());
}
}
@ -525,9 +532,8 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
* @param int $blogId
* @param string $userName
* @param string $password
* @param struct $category
* @access public
* @return void
* @param array $category
* @return mixed
*/
public function wpNewCategory($blogId, $userName, $password, $category)
{
@ -537,10 +543,9 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
/** 开始接受数据 */
$input['name'] = $category['name'];
$input['slug'] = Typecho_Common::slugName(empty($category['slug']) ? $category['name'] : $category['slug']);
$input['parent'] = isset($category['parent_id']) ? $category['parent_id'] :
(isset($category['parent']) ? $category['parent'] : 0);
$input['description'] = isset($category['description']) ? $category['description'] : $category['name'];
$input['slug'] = Common::slugName(empty($category['slug']) ? $category['name'] : $category['slug']);
$input['parent'] = $category['parent_id'] ?? ($category['parent'] ?? 0);
$input['description'] = $category['description'] ?? $category['name'];
$input['do'] = 'insert';
/** 调用已有组件 */
@ -549,11 +554,11 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
$categoryWidget = $this->singletonWidget('Widget_Metas_Category_Edit', null, $input, false);
$categoryWidget->action();
return $categoryWidget->mid;
} catch (Typecho_Widget_Exception $e) {
return new IXR_Error($e->getCode(), $e->getMessage());
} catch (Exception $e) {
return new Error($e->getCode(), $e->getMessage());
}
return new IXR_Error(403, _t('无法添加分类'));
return new Error(403, _t('无法添加分类'));
}
/**
@ -564,7 +569,7 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
* @param string $type 内容类型
* @return string
*/
private function wordpressToTypechoStatus($status, $type = 'post')
private function wordpressToTypechoStatus($status, $type = 'post'): string
{
if ('post' == $type) {
/** 文章状态 */
@ -590,15 +595,14 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
}
} elseif ('comment' == $type) {
switch ($status) {
case 'approve':
case 'publish':
case 'approved':
return 'approved';
case 'hold':
case 'waiting':
return 'waiting';
case 'spam':
return $status;
case 'approve':
case 'publish':
case 'approved':
default:
return 'approved';
}
@ -614,8 +618,7 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
* @param string $userName
* @param string $password
* @param int $pageId
* @access public
* @return bool
* @return mixed
*/
public function wpDeletePage($blogId, $userName, $password, $pageId)
{
@ -627,9 +630,9 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
try {
/** 此组件会进行复杂的权限检测 */
$this->singletonWidget('Widget_Contents_Page_Edit', null, "cid={$pageId}", false)->deletePage();
} catch (Typecho_Widget_Exception $e) {
} catch (Exception $e) {
/** 截获可能会抛出的异常(参见 Widget_Contents_Page_Edit 的 execute 方法) */
return new IXR_Error($e->getCode(), $e->getMessage());
return new Error($e->getCode(), $e->getMessage());
}
return true;
@ -642,7 +645,7 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
* @param int $pageId
* @param string $userName
* @param string $password
* @param struct $content
* @param array $content
* @param bool $publish
* @access public
* @return bool
@ -659,7 +662,7 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
* @param int $postId
* @param string $userName
* @param string $password
* @param struct $content
* @param array $content
* @param bool $publish
* @access public
* @return int
@ -677,7 +680,7 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
* @param string $userName
* @param string $password
* @param int $postId
* @param struct $content
* @param array $content
* @access public
* @return bool
*/
@ -721,8 +724,8 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
while ($pages->next()) {
$pageStructs[] = [
'dateCreated' => new IXR_Date($this->options->timezone + $pages->created),
'date_created_gmt' => new IXR_Date($this->options->timezone + $pages->created),
'dateCreated' => new Date($this->options->timezone + $pages->created),
'date_created_gmt' => new Date($this->options->timezone + $pages->created),
'page_id' => $pages->cid,
'page_title' => $pages->title,
'page_parent_id' => '0',
@ -783,7 +786,7 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
$meta = $this->singletonWidget('Widget_Abstract_Metas');
/** 构造出查询语句并且查询*/
$key = Typecho_Common::filterSearchQuery($category);
$key = Common::filterSearchQuery($category);
$key = '%' . $key . '%';
$select = $meta->select()->where('table.metas.type = ? AND (table.metas.name LIKE ? OR slug LIKE ?)', 'category', $key, $key);
@ -848,7 +851,7 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
'username' => $this->user->name,
'first_name' => '',
'last_name' => '',
'registered' => new IXR_Date($this->options->timezone + $this->user->created),
'registered' => new Date($this->options->timezone + $this->user->created),
'bio' => '',
'email' => $this->user->mail,
'nickname' => $this->user->screenName,
@ -1074,12 +1077,12 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
$struct = [];
if (empty($options)) {
$options = array_keys($this->_wpOptions);
$options = array_keys($this->wpOptions);
}
foreach ($options as $option) {
if (isset($this->_wpOptions[$option])) {
$struct[$option] = $this->_wpOptions[$option];
if (isset($this->wpOptions[$option])) {
$struct[$option] = $this->wpOptions[$option];
if (isset($struct[$option]['option'])) {
$struct[$option]['value'] = $this->options->{$struct[$option]['option']};
unset($struct[$option]['option']);
@ -1109,17 +1112,17 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
$struct = [];
foreach ($options as $option => $value) {
if (isset($this->_wpOptions[$option])) {
$struct[$option] = $this->_wpOptions[$option];
if (isset($this->wpOptions[$option])) {
$struct[$option] = $this->wpOptions[$option];
if (isset($struct[$option]['option'])) {
$struct[$option]['value'] = $this->options->{$struct[$option]['option']};
unset($struct[$option]['option']);
}
if (!$this->_wpOptions[$option]['readonly'] && isset($this->_wpOptions[$option]['option'])) {
if (!$this->wpOptions[$option]['readonly'] && isset($this->wpOptions[$option]['option'])) {
if ($this->db->query($this->db->update('table.options')
->rows(['value' => $value])
->where('name = ?', $this->_wpOptions[$option]['option'])) > 0) {
->where('name = ?', $this->wpOptions[$option]['option'])) > 0) {
$struct[$option]['value'] = $value;
}
}
@ -1149,15 +1152,15 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
$comment = $this->singletonWidget('Widget_Comments_Edit', null, 'do=get&coid=' . intval($commentId), false);
if (!$comment->have()) {
return new IXR_Error(404, _t('评论不存在'));
return new Error(404, _t('评论不存在'));
}
if (!$comment->commentIsWriteable()) {
return new IXR_Error(403, _t('没有获取评论的权限'));
return new Error(403, _t('没有获取评论的权限'));
}
return [
'date_created_gmt' => new IXR_Date($this->options->timezone + $comment->created),
'date_created_gmt' => new Date($this->options->timezone + $comment->created),
'user_id' => $comment->authorId,
'comment_id' => $comment->coid,
'parent' => $comment->parent,
@ -1217,7 +1220,7 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
while ($comments->next()) {
$commentsStruct[] = [
'date_created_gmt' => new IXR_Date($this->options->timezone + $comments->created),
'date_created_gmt' => new Date($this->options->timezone + $comments->created),
'user_id' => $comments->authorId,
'comment_id' => $comments->coid,
'parent' => $comments->parent,
@ -1259,7 +1262,7 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
$where = $this->db->sql()->where('coid = ?', $commentId);
if (!$commentWidget->commentIsWriteable($where)) {
return new IXR_Error(403, _t('无法编辑此评论'));
return new Error(403, _t('无法编辑此评论'));
}
return intval($this->singletonWidget('Widget_Abstract_Comments')->delete($where)) > 0;
@ -1288,7 +1291,7 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
$where = $this->db->sql()->where('coid = ?', $commentId);
if (!$commentWidget->commentIsWriteable($where)) {
return new IXR_Error(403, _t('无法编辑此评论'));
return new Error(403, _t('无法编辑此评论'));
}
$input = [];
@ -1320,7 +1323,7 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
$result = $commentWidget->update((array)$input, $where);
if (!$result) {
return new IXR_Error(404, _t('评论不存在'));
return new Error(404, _t('评论不存在'));
}
return true;
@ -1348,13 +1351,13 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
$post = $this->singletonWidget('Widget_Archive', 'type=single', 'cid=' . $path, false);
} else {
/** 检查目标地址是否正确*/
$pathInfo = Typecho_Common::url(substr($path, strlen($this->options->index)), '/');
$pathInfo = Common::url(substr($path, strlen($this->options->index)), '/');
$post = Typecho_Router::match($pathInfo);
}
/** 这样可以得到cid或者slug*/
if (!isset($post) || !($post instanceof Widget_Archive) || !$post->have() || !$post->is('single')) {
return new IXR_Error(404, _t('这个目标地址不存在'));
return new Error(404, _t('这个目标地址不存在'));
}
$input = [];
@ -1386,10 +1389,10 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
$commentWidget->action();
return intval($commentWidget->coid);
} catch (Typecho_Exception $e) {
return new IXR_Error(500, $e->getMessage());
return new Error(500, $e->getMessage());
}
return new IXR_Error(403, _t('无法添加评论'));
return new Error(403, _t('无法添加评论'));
}
/**
@ -1435,7 +1438,7 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
while ($attachments->next()) {
$attachmentsStruct[] = [
'attachment_id' => $attachments->cid,
'date_created_gmt' => new IXR_Date($this->options->timezone + $attachments->created),
'date_created_gmt' => new Date($this->options->timezone + $attachments->created),
'parent' => $attachments->parent,
'link' => $attachments->attachment->url,
'title' => $attachments->title,
@ -1473,7 +1476,7 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
$attachment = $this->singletonWidget('Widget_Contents_Attachment_Edit', null, "cid={$attachmentId}");
$struct = [
'attachment_id' => $attachment->cid,
'date_created_gmt' => new IXR_Date($this->options->timezone + $attachment->created),
'date_created_gmt' => new Date($this->options->timezone + $attachment->created),
'parent' => $attachment->parent,
'link' => $attachment->attachment->url,
'title' => $attachment->title,
@ -1506,8 +1509,8 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
try {
$post = $this->singletonWidget('Widget_Contents_Post_Edit', null, "cid={$postId}");
} catch (Typecho_Widget_Exception $e) {
return new IXR_Error($e->getCode(), $e->getMessage());
} catch (Exception $e) {
return new Error($e->getCode(), $e->getMessage());
}
/** 对文章内容做截取处理以获得description和text_more*/
@ -1517,7 +1520,7 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
$tags = array_column($post->tags, 'name');
$postStruct = [
'dateCreated' => new IXR_Date($this->options->timezone + $post->created),
'dateCreated' => new Date($this->options->timezone + $post->created),
'userid' => $post->authorId,
'postid' => $post->cid,
'description' => $excerpt,
@ -1535,7 +1538,7 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
'wp_author' => $post->author->name,
'wp_author_id' => $post->authorId,
'wp_author_display_name' => $post->author->screenName,
'date_created_gmt' => new IXR_Date($post->created),
'date_created_gmt' => new Date($post->created),
'post_status' => $this->typechoToWordpressStatus($post->status, 'post'),
'custom_fields' => [],
'sticky' => 0
@ -1574,7 +1577,7 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
$tags = array_column($posts->tags, 'name');
$postStructs[] = [
'dateCreated' => new IXR_Date($this->options->timezone + $posts->created),
'dateCreated' => new Date($this->options->timezone + $posts->created),
'userid' => $posts->authorId,
'postid' => $posts->cid,
'description' => $excerpt,
@ -1593,12 +1596,12 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
'wp_author' => $posts->author->name,
'wp_author_id' => $posts->authorId,
'wp_author_display_name' => $posts->author->screenName,
'date_created_gmt' => new IXR_Date($posts->created),
'date_created_gmt' => new Date($posts->created),
'post_status' => $this->typechoToWordpressStatus(($posts->hasSaved || 'post_draft' == $posts->type) ? 'draft' : $posts->status, 'post'),
'custom_fields' => [],
'wp_post_format' => 'standard',
'date_modified' => new IXR_Date($this->options->timezone + $posts->modified),
'date_modified_gmt' => new IXR_Date($posts->modified),
'date_modified' => new Date($this->options->timezone + $posts->modified),
'date_modified_gmt' => new Date($posts->modified),
'wp_post_thumbnail' => '',
'sticky' => 0
];
@ -1660,7 +1663,7 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
$result = Widget_Upload::uploadHandle($data);
if (false === $result) {
return new IXR_Error(500, _t('上传失败'));
return new Error(500, _t('上传失败'));
} else {
$insertId = $this->insert([
@ -1710,11 +1713,11 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
$postTitleStructs = [];
while ($posts->next()) {
$postTitleStructs[] = [
'dateCreated' => new IXR_Date($this->options->timezone + $posts->created),
'dateCreated' => new Date($this->options->timezone + $posts->created),
'userid' => $posts->authorId,
'postid' => $posts->cid,
'title' => $posts->title,
'date_created_gmt' => new IXR_Date($this->options->timezone + $posts->created)
'date_created_gmt' => new Date($this->options->timezone + $posts->created)
];
}
@ -1766,8 +1769,8 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
try {
$post = $this->singletonWidget('Widget_Contents_Post_Edit', null, "cid={$postId}");
} catch (Typecho_Widget_Exception $e) {
return new IXR_Error($e->getCode(), $e->getMessage());
} catch (Exception $e) {
return new Error($e->getCode(), $e->getMessage());
}
/** 格式化categories*/
@ -1800,8 +1803,8 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
try {
$post = $this->singletonWidget('Widget_Contents_Post_Edit', null, "cid={$postId}");
} catch (Typecho_Widget_Exception $e) {
return new IXR_Error($e->getCode(), $e->getMessage());
} catch (Exception $e) {
return new Error($e->getCode(), $e->getMessage());
}
$post->setCategories($postId, array_column($categories, 'categoryId'),
@ -1830,7 +1833,7 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
/** 提交查询 */
$post = $this->db->fetchRow($select, [$this, 'push']);
if ($this->authorId != $this->user->uid && !$this->checkAccess($userName, $password, 'administrator')) {
return new IXR_Error(403, '权限不足.');
return new Error(403, '权限不足.');
}
/** 暂时只做成发布*/
@ -1912,8 +1915,8 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
try {
$post = $this->singletonWidget('Widget_Contents_Post_Edit', null, "cid={$postId}");
} catch (Typecho_Widget_Exception $e) {
return new IXR_Error($e->getCode(), $e->getMessage());
} catch (Exception $e) {
return new Error($e->getCode(), $e->getMessage());
}
$categories = array_column($post->categories, 'name');
@ -1924,7 +1927,7 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
$struct = [
'userid' => $post->authorId,
'dateCreated' => new IXR_Date($this->options->timezone + $post->created),
'dateCreated' => new Date($this->options->timezone + $post->created),
'content' => $content,
'postid' => $post->cid
];
@ -1948,8 +1951,8 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
}
try {
$this->singletonWidget('Widget_Contents_Post_Edit', null, "cid={$postId}", false)->deletePost();
} catch (Typecho_Widget_Exception $e) {
return new IXR_Error($e->getCode(), $e->getMessage());
} catch (Exception $e) {
return new Error($e->getCode(), $e->getMessage());
}
}
@ -1981,14 +1984,14 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
$struct = [
'userid' => $posts->authorId,
'dateCreated' => new IXR_Date($this->options->timezone + $posts->created),
'dateCreated' => new Date($this->options->timezone + $posts->created),
'content' => $content,
'postid' => $posts->cid,
];
$postStructs[] = $struct;
}
if (null == $postStructs) {
return new IXR_Error('404', '没有任何文章');
return new Error('404', '没有任何文章');
}
return $postStructs;
}
@ -2037,28 +2040,28 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
*
* @param string $source
* @param string $target
* @access public
* @return void
* @return mixed
* @throws \Exception
*/
public function pingbackPing($source, $target)
{
/** 检查目标地址是否正确*/
$pathInfo = Typecho_Common::url(substr($target, strlen($this->options->index)), '/');
$post = Typecho_Router::match($pathInfo);
$pathInfo = Common::url(substr($target, strlen($this->options->index)), '/');
$post = Router::match($pathInfo);
/** 检查源地址是否合法 */
$params = parse_url($source);
if (false === $params || !in_array($params['scheme'], ['http', 'https'])) {
return new IXR_Error(16, _t('源地址服务器错误'));
return new Error(16, _t('源地址服务器错误'));
}
if (!Typecho_Common::checkSafeHost($params['host'])) {
return new IXR_Error(16, _t('源地址服务器错误'));
if (!Common::checkSafeHost($params['host'])) {
return new Error(16, _t('源地址服务器错误'));
}
/** 这样可以得到cid或者slug*/
if (!($post instanceof Widget_Archive) || !$post->have() || !$post->is('single')) {
return new IXR_Error(33, _t('这个目标地址不存在'));
return new Error(33, _t('这个目标地址不存在'));
}
if ($post) {
@ -2073,7 +2076,7 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
if ($pingNum <= 0) {
/** 检查源地址是否存在*/
if (!($http = Typecho_Http_Client::get())) {
return new IXR_Error(16, _t('源地址服务器错误'));
return new Error(16, _t('源地址服务器错误'));
}
try {
@ -2086,24 +2089,24 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
if (!$http->getResponseHeader('x-pingback')) {
preg_match_all("/<link[^>]*rel=[\"']([^\"']*)[\"'][^>]*href=[\"']([^\"']*)[\"'][^>]*>/i", $response, $out);
if (!isset($out[1]['pingback'])) {
return new IXR_Error(50, _t('源地址不支持PingBack'));
return new Error(50, _t('源地址不支持PingBack'));
}
}
} else {
return new IXR_Error(16, _t('源地址服务器错误'));
return new Error(16, _t('源地址服务器错误'));
}
} catch (Exception $e) {
return new IXR_Error(16, _t('源地址服务器错误'));
return new Error(16, _t('源地址服务器错误'));
}
/** 现在开始插入以及邮件提示了 $response就是第一行请求时返回的数组*/
preg_match("/\<title\>([^<]*?)\<\/title\\>/is", $response, $matchTitle);
$finalTitle = Typecho_Common::removeXSS(trim(strip_tags($matchTitle[1])));
$finalTitle = Common::removeXSS(trim(strip_tags($matchTitle[1])));
/** 干掉html tag只留下<a>*/
$text = Typecho_Common::stripTags($response, '<a href="">');
$text = Common::stripTags($response, '<a href="">');
/** 此处将$target quote,留着后面用*/
$pregLink = preg_quote($target);
@ -2118,7 +2121,7 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
if (preg_match("|<a[^>]*href=[\"']{$pregLink}[\"'][^>]*>(.*?)</a>|", $line)) {
if (strlen($line) > strlen($finalText)) {
/** <a>也要干掉,*/
$finalText = Typecho_Common::stripTags($line);
$finalText = Common::stripTags($line);
}
}
}
@ -2126,18 +2129,18 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
/** 截取一段字*/
if (null == trim($finalText)) {
return new IXR_Error('17', _t('源地址中不包括目标地址'));
return new Error('17', _t('源地址中不包括目标地址'));
}
$finalText = '[...]' . Typecho_Common::subStr($finalText, 0, 200, '') . '[...]';
$finalText = '[...]' . Common::subStr($finalText, 0, 200, '') . '[...]';
$pingback = [
'cid' => $post->cid,
'created' => $this->options->time,
'agent' => $this->request->getAgent(),
'ip' => $this->request->getIp(),
'author' => Typecho_Common::subStr($finalTitle, 0, 150, '...'),
'url' => Typecho_Common::safeUrl($source),
'author' => Common::subStr($finalTitle, 0, 150, '...'),
'url' => Common::safeUrl($source),
'text' => $finalText,
'ownerId' => $post->author->uid,
'type' => 'pingback',
@ -2157,13 +2160,13 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
/** todo:发送邮件提示*/
} else {
return new IXR_Error(48, _t('PingBack已经存在'));
return new Error(48, _t('PingBack已经存在'));
}
} else {
return new IXR_Error(49, _t('目标地址禁止Ping'));
return new Error(49, _t('目标地址禁止Ping'));
}
} else {
return new IXR_Error(33, _t('这个目标地址不存在'));
return new Error(33, _t('这个目标地址不存在'));
}
}
@ -2176,10 +2179,10 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
*/
public function hookAfterCall($methodName)
{
if (!empty($this->_usedWidgetNameList)) {
foreach ($this->_usedWidgetNameList as $key => $widgetName) {
if (!empty($this->usedWidgetNameList)) {
foreach ($this->usedWidgetNameList as $key => $widgetName) {
$this->destroy($widgetName);
unset($this->_usedWidgetNameList[$key]);
unset($this->usedWidgetNameList[$key]);
}
}
}
@ -2193,7 +2196,7 @@ class Widget_XmlRpc extends Widget_Abstract_Contents implements Widget_Interface
public function action()
{
if (0 == $this->options->allowXmlRpc) {
throw new Typecho_Widget_Exception(_t('请求的地址不存在'), 404);
throw new Exception(_t('请求的地址不存在'), 404);
}
if (isset($this->request->rsd)) {
@ -2252,12 +2255,11 @@ EOF;
</manifest>
EOF;
} else {
$api = [
/** WordPress API */
'wp.getPage' => [$this, 'wpGetPage'],
'wp.getPages' => [$this, 'wpGetPages'],
'wp.newPage' => [$this, 'wpNewPage'],
'wp.getPages' => [$this, 'wpGetPages', ['int', 'string', 'string']],
'wp.newPage' => [$this, 'wpNewPage', ['int', 'string', 'string', 'struct', 'boolean']],
'wp.deletePage' => [$this, 'wpDeletePage'],
'wp.editPage' => [$this, 'wpEditPage'],
'wp.getPageList' => [$this, 'wpGetPageList'],
@ -2334,7 +2336,7 @@ EOF;
}
/** 直接把初始化放到这里 */
new IXR_Server($api);
new Server($api);
}
}
}