Merge commit 'daef17d7eb250419ff84f499e87d25ee71daac87' into dev

# Conflicts:
#	var/Utils/Upgrade.php
This commit is contained in:
joyqi 2023-03-29 16:20:01 +08:00
commit 6de71129a4
28 changed files with 142 additions and 71 deletions

View File

@ -1,13 +1,13 @@
<?php if(!defined('__TYPECHO_ADMIN__')) exit; ?>
<div class="typecho-foot" role="contentinfo">
<div class="copyright">
<a href="http://typecho.org" class="i-logo-s">Typecho</a>
<p><?php _e('由 <a href="http://typecho.org">%s</a> 强力驱动, 版本 %s', $options->software, $options->version); ?></p>
<a href="https://typecho.org" class="i-logo-s">Typecho</a>
<p><?php _e('由 <a href="https://typecho.org">%s</a> 强力驱动, 版本 %s', $options->software, $options->version); ?></p>
</div>
<nav class="resource">
<a href="http://docs.typecho.org"><?php _e('帮助文档'); ?></a> &bull;
<a href="http://forum.typecho.org"><?php _e('支持论坛'); ?></a> &bull;
<a href="https://docs.typecho.org"><?php _e('帮助文档'); ?></a> &bull;
<a href="https://forum.typecho.org"><?php _e('支持论坛'); ?></a> &bull;
<a href="https://github.com/typecho/typecho/issues"><?php _e('报告错误'); ?></a> &bull;
<a href="http://typecho.org/download"><?php _e('资源下载'); ?></a>
<a href="https://typecho.org/download"><?php _e('资源下载'); ?></a>
</nav>
</div>

View File

@ -77,6 +77,6 @@ $defaultFields = isset($post) ? $post->getDefaultFieldItems() : $page->getDefaul
</table>
<div class="description clearfix">
<button type="button" class="btn btn-xs operate-add"><?php _e('+添加字段'); ?></button>
<?php _e('自定义字段可以扩展你的模板功能, 使用方法参见 <a href="http://docs.typecho.org/help/custom-fields">帮助文档</a>'); ?>
<?php _e('自定义字段可以扩展你的模板功能, 使用方法参见 <a href="https://docs.typecho.org/help/custom-fields">帮助文档</a>'); ?>
</div>
</section>

View File

@ -13,7 +13,7 @@ include 'header.php';
?>
<div class="typecho-login-wrap">
<div class="typecho-login">
<h1><a href="http://typecho.org" class="i-logo">Typecho</a></h1>
<h1><a href="https://typecho.org" class="i-logo">Typecho</a></h1>
<form action="<?php $options->loginAction(); ?>" method="post" name="login" role="form">
<p>
<label for="name" class="sr-only"><?php _e('用户名'); ?></label>
@ -25,7 +25,7 @@ include 'header.php';
</p>
<p class="submit">
<button type="submit" class="btn btn-l w-100 primary"><?php _e('登录'); ?></button>
<input type="hidden" name="referer" value="<?php echo htmlspecialchars($request->get('referer') ?? ''); ?>" />
<input type="hidden" name="referer" value="<?php echo $request->filter('html')->get('referer'); ?>" />
</p>
<p>
<label for="remember">

View File

@ -21,9 +21,9 @@ $isAllComments = ('on' == $request->get('__typecho_all_comments') || 'on' == \Ty
</ul>
<ul class="typecho-option-tabs">
<li<?php if(!isset($request->status) || 'approved' == $request->get('status')): ?> class="current"<?php endif; ?>><a href="<?php $options->adminUrl('manage-comments.php'
. (isset($request->cid) ? '?cid=' . $request->cid : '')); ?>"><?php _e('已通过'); ?></a></li>
. (isset($request->cid) ? '?cid=' . $request->filter('encode')->cid : '')); ?>"><?php _e('已通过'); ?></a></li>
<li<?php if('waiting' == $request->get('status')): ?> class="current"<?php endif; ?>><a href="<?php $options->adminUrl('manage-comments.php?status=waiting'
. (isset($request->cid) ? '&cid=' . $request->cid : '')); ?>"><?php _e('待审核'); ?>
. (isset($request->cid) ? '&cid=' . $request->filter('encode')->cid : '')); ?>"><?php _e('待审核'); ?>
<?php if(!$isAllComments && $stat->myWaitingCommentsNum > 0 && !isset($request->cid)): ?>
<span class="balloon"><?php $stat->myWaitingCommentsNum(); ?></span>
<?php elseif($isAllComments && $stat->waitingCommentsNum > 0 && !isset($request->cid)): ?>
@ -33,7 +33,7 @@ $isAllComments = ('on' == $request->get('__typecho_all_comments') || 'on' == \Ty
<?php endif; ?>
</a></li>
<li<?php if('spam' == $request->get('status')): ?> class="current"<?php endif; ?>><a href="<?php $options->adminUrl('manage-comments.php?status=spam'
. (isset($request->cid) ? '&cid=' . $request->cid : '')); ?>"><?php _e('垃圾'); ?>
. (isset($request->cid) ? '&cid=' . $request->filter('encode')->cid : '')); ?>"><?php _e('垃圾'); ?>
<?php if(!$isAllComments && $stat->mySpamCommentsNum > 0 && !isset($request->cid)): ?>
<span class="balloon"><?php $stat->mySpamCommentsNum(); ?></span>
<?php elseif($isAllComments && $stat->spamCommentsNum > 0 && !isset($request->cid)): ?>
@ -66,15 +66,15 @@ $isAllComments = ('on' == $request->get('__typecho_all_comments') || 'on' == \Ty
<?php if ('' != $request->keywords || '' != $request->category): ?>
<a href="<?php $options->adminUrl('manage-comments.php'
. (isset($request->status) || isset($request->cid) ? '?' .
(isset($request->status) ? 'status=' . htmlspecialchars($request->get('status')) : '') .
(isset($request->cid) ? (isset($request->status) ? '&' : '') . 'cid=' . htmlspecialchars($request->get('cid')) : '') : '')); ?>"><?php _e('&laquo; 取消筛选'); ?></a>
(isset($request->status) ? 'status=' . $request->filter('encode')->status : '') .
(isset($request->cid) ? (isset($request->status) ? '&' : '') . 'cid=' . $request->filter('encode')->cid : '') : '')); ?>"><?php _e('&laquo; 取消筛选'); ?></a>
<?php endif; ?>
<input type="text" class="text-s" placeholder="<?php _e('请输入关键字'); ?>" value="<?php echo htmlspecialchars($request->keywords ?? ''); ?>"<?php if ('' == $request->keywords): ?> onclick="value='';name='keywords';" <?php else: ?> name="keywords"<?php endif; ?>/>
<input type="text" class="text-s" placeholder="<?php _e('请输入关键字'); ?>" value="<?php echo $request->filter('html')->keywords; ?>"<?php if ('' == $request->keywords): ?> onclick="value='';name='keywords';" <?php else: ?> name="keywords"<?php endif; ?>/>
<?php if(isset($request->status)): ?>
<input type="hidden" value="<?php echo htmlspecialchars($request->get('status')); ?>" name="status" />
<input type="hidden" value="<?php echo $request->filter('html')->status; ?>" name="status" />
<?php endif; ?>
<?php if(isset($request->cid)): ?>
<input type="hidden" value="<?php echo htmlspecialchars($request->get('cid')); ?>" name="cid" />
<input type="hidden" value="<?php echo $request->filter('html')->cid; ?>" name="cid" />
<?php endif; ?>
<button type="submit" class="btn btn-s"><?php _e('筛选'); ?></button>
</div>
@ -183,7 +183,7 @@ $isAllComments = ('on' == $request->get('__typecho_all_comments') || 'on' == \Ty
</div><!-- end .typecho-table-wrap -->
<?php if(isset($request->cid)): ?>
<input type="hidden" value="<?php echo htmlspecialchars($request->get('cid')); ?>" name="cid" />
<input type="hidden" value="<?php echo $request->filter('html')->cid; ?>" name="cid" />
<?php endif; ?>
</form><!-- end .operate-form -->

View File

@ -36,7 +36,7 @@ $attachments = \Widget\Contents\Attachment\Admin::alloc();
<a href="<?php $options->adminUrl('manage-medias.php'); ?>"><?php _e('&laquo; 取消筛选'); ?></a>
<?php endif; ?>
<input type="text" class="text-s" placeholder="<?php _e('请输入关键字'); ?>"
value="<?php echo htmlspecialchars($request->keywords ?? ''); ?>"<?php if ('' == $request->keywords): ?> onclick="value='';name='keywords';" <?php else: ?> name="keywords"<?php endif; ?>/>
value="<?php echo $request->filter('html')->keywords; ?>"<?php if ('' == $request->keywords): ?> onclick="value='';name='keywords';" <?php else: ?> name="keywords"<?php endif; ?>/>
<button type="submit" class="btn btn-s"><?php _e('筛选'); ?></button>
</div>
</form>

View File

@ -39,7 +39,7 @@ $pages = \Widget\Contents\Page\Admin::alloc();
<a href="<?php $options->adminUrl('manage-pages.php'); ?>"><?php _e('&laquo; 取消筛选'); ?></a>
<?php endif; ?>
<input type="text" class="text-s" placeholder="<?php _e('请输入关键字'); ?>"
value="<?php echo htmlspecialchars($request->keywords ?? ''); ?>" name="keywords"/>
value="<?php echo $request->filter('html')->keywords; ?>" name="keywords"/>
<button type="submit" class="btn btn-s"><?php _e('筛选'); ?></button>
</div>
</form>

View File

@ -26,11 +26,11 @@ $isAllPosts = ('on' == $request->get('__typecho_all_posts') || 'on' == \Typecho\
<ul class="typecho-option-tabs">
<li<?php if (!isset($request->status) || 'all' == $request->get('status')): ?> class="current"<?php endif; ?>>
<a href="<?php $options->adminUrl('manage-posts.php'
. (isset($request->uid) ? '?uid=' . $request->uid : '')); ?>"><?php _e('可用'); ?></a>
. (isset($request->uid) ? '?uid=' . $request->filter('encode')->uid : '')); ?>"><?php _e('可用'); ?></a>
</li>
<li<?php if ('waiting' == $request->get('status')): ?> class="current"<?php endif; ?>><a
href="<?php $options->adminUrl('manage-posts.php?status=waiting'
. (isset($request->uid) ? '&uid=' . $request->uid : '')); ?>"><?php _e('待审核'); ?>
. (isset($request->uid) ? '&uid=' . $request->filter('encode')->uid : '')); ?>"><?php _e('待审核'); ?>
<?php if (!$isAllPosts && $stat->myWaitingPostsNum > 0 && !isset($request->uid)): ?>
<span class="balloon"><?php $stat->myWaitingPostsNum(); ?></span>
<?php elseif ($isAllPosts && $stat->waitingPostsNum > 0 && !isset($request->uid)): ?>
@ -41,7 +41,7 @@ $isAllPosts = ('on' == $request->get('__typecho_all_posts') || 'on' == \Typecho\
</a></li>
<li<?php if ('draft' == $request->get('status')): ?> class="current"<?php endif; ?>><a
href="<?php $options->adminUrl('manage-posts.php?status=draft'
. (isset($request->uid) ? '&uid=' . $request->uid : '')); ?>"><?php _e('草稿'); ?>
. (isset($request->uid) ? '&uid=' . $request->filter('encode')->uid : '')); ?>"><?php _e('草稿'); ?>
<?php if (!$isAllPosts && $stat->myDraftPostsNum > 0 && !isset($request->uid)): ?>
<span class="balloon"><?php $stat->myDraftPostsNum(); ?></span>
<?php elseif ($isAllPosts && $stat->draftPostsNum > 0 && !isset($request->uid)): ?>
@ -87,11 +87,11 @@ $isAllPosts = ('on' == $request->get('__typecho_all_posts') || 'on' == \Typecho\
<?php if ('' != $request->keywords || '' != $request->category): ?>
<a href="<?php $options->adminUrl('manage-posts.php'
. (isset($request->status) || isset($request->uid) ? '?' .
(isset($request->status) ? 'status=' . htmlspecialchars($request->get('status')) : '') .
(isset($request->uid) ? '?uid=' . htmlspecialchars($request->get('uid')) : '') : '')); ?>"><?php _e('&laquo; 取消筛选'); ?></a>
(isset($request->status) ? 'status=' . $request->filter('encode')->status : '') .
(isset($request->uid) ? (isset($request->status) ? '&' : '') . 'uid=' . $request->filter('encode')->uid : '') : '')); ?>"><?php _e('&laquo; 取消筛选'); ?></a>
<?php endif; ?>
<input type="text" class="text-s" placeholder="<?php _e('请输入关键字'); ?>"
value="<?php echo htmlspecialchars($request->keywords ?? ''); ?>" name="keywords"/>
value="<?php echo $request->filter('html')->keywords; ?>" name="keywords"/>
<select name="category">
<option value=""><?php _e('所有分类'); ?></option>
<?php \Widget\Metas\Category\Rows::alloc()->to($category); ?>
@ -102,11 +102,11 @@ $isAllPosts = ('on' == $request->get('__typecho_all_posts') || 'on' == \Typecho\
</select>
<button type="submit" class="btn btn-s"><?php _e('筛选'); ?></button>
<?php if (isset($request->uid)): ?>
<input type="hidden" value="<?php echo htmlspecialchars($request->get('uid')); ?>"
<input type="hidden" value="<?php echo $request->filter('html')->uid; ?>"
name="uid"/>
<?php endif; ?>
<?php if (isset($request->status)): ?>
<input type="hidden" value="<?php echo htmlspecialchars($request->get('status')); ?>"
<input type="hidden" value="<?php echo $request->filter('html')->status; ?>"
name="status"/>
<?php endif; ?>
</div>
@ -179,8 +179,8 @@ $isAllPosts = ('on' == $request->get('__typecho_all_posts') || 'on' == \Typecho\
<?php foreach ($categories as $key => $val): ?>
<?php echo '<a href="';
$options->adminUrl('manage-posts.php?category=' . $val['mid']
. (isset($request->uid) ? '&uid=' . $request->uid : '')
. (isset($request->status) ? '&status=' . $request->status : ''));
. (isset($request->uid) ? '&uid=' . $request->filter('encode')->uid : '')
. (isset($request->status) ? '&status=' . $request->filter('encode')->status : ''));
echo '">' . $val['name'] . '</a>' . ($key < $length - 1 ? ', ' : ''); ?>
<?php endforeach; ?>
</td>

View File

@ -31,7 +31,7 @@ $users = \Widget\Users\Admin::alloc();
<a href="<?php $options->adminUrl('manage-users.php'); ?>"><?php _e('&laquo; 取消筛选'); ?></a>
<?php endif; ?>
<input type="text" class="text-s" placeholder="<?php _e('请输入关键字'); ?>"
value="<?php echo htmlspecialchars($request->keywords ?? ''); ?>" name="keywords"/>
value="<?php echo $request->filter('html')->keywords; ?>" name="keywords"/>
<button type="submit" class="btn btn-s"><?php _e('筛选'); ?></button>
</div>
</form>

View File

@ -15,7 +15,7 @@ include 'header.php';
?>
<div class="typecho-login-wrap">
<div class="typecho-login">
<h1><a href="http://typecho.org" class="i-logo">Typecho</a></h1>
<h1><a href="https://typecho.org" class="i-logo">Typecho</a></h1>
<form action="<?php $options->registerAction(); ?>" method="post" name="register" role="form">
<p>
<label for="name" class="sr-only"><?php _e('用户名'); ?></label>

View File

@ -1700,8 +1700,8 @@ else
// The default text that appears in the dialog input box when entering
// links.
var imageDefaultText = "http://";
var linkDefaultText = "http://";
var imageDefaultText = "https://";
var linkDefaultText = "https://";
// -------------------------------------------------------------------
// END OF YOUR CHANGES

View File

@ -705,7 +705,7 @@ function install_step_1()
</p>
<h3><?php _e('许可及协议'); ?></h3>
<ul>
<li><?php _e('Typecho 基于 <a href="http://www.gnu.org/copyleft/gpl.html">GPL</a> 协议发布, 我们允许用户在 GPL 协议许可的范围内使用, 拷贝, 修改和分发此程序.'); ?>
<li><?php _e('Typecho 基于 <a href="https://www.gnu.org/copyleft/gpl.html">GPL</a> 协议发布, 我们允许用户在 GPL 协议许可的范围内使用, 拷贝, 修改和分发此程序.'); ?>
<?php _e('在GPL许可的范围内, 您可以自由地将其用于商业以及非商业用途.'); ?></li>
<li><?php _e('Typecho 软件由其社区提供支持, 核心开发团队负责维护程序日常开发工作以及新特性的制定.'); ?>
<?php _e('如果您遇到使用上的问题, 程序中的 BUG, 以及期许的新功能, 欢迎您在社区中交流或者直接向我们贡献代码.'); ?>
@ -924,7 +924,9 @@ function install_step_2_perform()
'dbPassword' => null,
'dbCharset' => 'utf8mb4',
'dbDatabase' => null,
'dbEngine' => 'InnoDB'
'dbEngine' => 'InnoDB',
'dbSslCa' => null,
'dbSslVerify' => 'on',
],
'Pgsql' => [
'dbHost' => 'localhost',
@ -952,7 +954,9 @@ function install_step_2_perform()
'dbEngine' => $request->getServer('TYPECHO_DB_ENGINE'),
'dbPrefix' => $request->getServer('TYPECHO_DB_PREFIX', 'typecho_'),
'dbAdapter' => $request->getServer('TYPECHO_DB_ADAPTER', install_get_current_db_driver()),
'dbNext' => $request->getServer('TYPECHO_DB_NEXT', 'none')
'dbNext' => $request->getServer('TYPECHO_DB_NEXT', 'none'),
'dbSslCa' => $request->getServer('TYPECHO_DB_SSL_CA'),
'dbSslVerify' => $request->getServer('TYPECHO_DB_SSL_VERIFY', 'on'),
];
} else {
$config = $request->from([
@ -967,7 +971,9 @@ function install_step_2_perform()
'dbEngine',
'dbPrefix',
'dbAdapter',
'dbNext'
'dbNext',
'dbSslCa',
'dbSslVerify',
]);
}
@ -1005,6 +1011,8 @@ function install_step_2_perform()
->addRule('dbDatabase', 'required', _t('确认您的配置'))
->addRule('dbEngine', 'required', _t('确认您的配置'))
->addRule('dbEngine', 'enum', _t('确认您的配置'), ['InnoDB', 'MyISAM'])
->addRule('dbSslCa', 'file_exists', _t('确认您的配置'))
->addRule('dbSslVerify', 'enum', _t('确认您的配置'), ['on', 'off'])
->run($config);
break;
case 'Pgsql':
@ -1041,7 +1049,7 @@ function install_step_2_perform()
}
foreach ($configMap[$type] as $key => $value) {
$dbConfig[strtolower(substr($key, 2))] = $config[$key];
$dbConfig[lcfirst(substr($key, 2))] = $config[$key];
}
// intval port number
@ -1049,6 +1057,11 @@ function install_step_2_perform()
$dbConfig['port'] = intval($dbConfig['port']);
}
// bool ssl verify
if (isset($dbConfig['sslVerify'])) {
$dbConfig['sslVerify'] = $dbConfig['sslVerify'] == 'on';
}
if (isset($dbConfig['file']) && preg_match("/^[a-z0-9]+\.[a-z0-9]{2,}$/i", $dbConfig['file'])) {
$dbConfig['file'] = __DIR__ . '/usr/' . $dbConfig['file'];
}
@ -1064,7 +1077,7 @@ function install_step_2_perform()
$installDb->addServer($dbConfig, \Typecho\Db::READ | \Typecho\Db::WRITE);
$installDb->query('SELECT 1=1');
} catch (\Typecho\Db\Adapter\ConnectionException $e) {
install_raise_error(_t('对不起, 无法连接数据库, 请先检查数据库配置再继续进行安装'));
install_raise_error(_t('对不起, 无法连接数据库, 请先检查数据库配置再继续进行安装: "%s"', $e->getMessage()));
} catch (\Typecho\Db\Exception $e) {
install_raise_error(_t('安装程序捕捉到以下错误: "%s". 程序被终止, 请检查您的配置信息.', $e->getMessage()));
}
@ -1460,7 +1473,7 @@ function install_dispatch()
</head>
<body>
<div class="body container">
<h1><a href="http://typecho.org" target="_blank" class="i-logo">Typecho</a></h1>
<h1><a href="https://typecho.org" target="_blank" class="i-logo">Typecho</a></h1>
<?php $method(); ?>
</div>
</body>

View File

@ -63,4 +63,22 @@
</select>
</li>
</ul>
</details>
<ul class="typecho-option">
<li>
<label class="typecho-label" for="dbSslCa"><?php _e('数据库 SSL 证书'); ?></label>
<input type="text" class="text" name="dbSslCa" id="dbSslCa"/>
<p class="description"><?php _e('如果您的数据库启用了 SSL请填写 CA 证书路径,否则请留空'); ?></p>
</li>
</ul>
<ul class="typecho-option">
<li>
<label class="typecho-label" for="dbSslVerify"><?php _e('启用数据库 SSL 服务端证书验证'); ?></label>
<select name="dbSslVerify" id="dbSslVerify">
<option value="on"><?php _e('启用'); ?></option>
<option value="off"><?php _e('不启用'); ?></option>
</select>
</li>
</ul>
</details>

View File

@ -6,7 +6,7 @@
<footer id="footer" role="contentinfo">
&copy; <?php echo date('Y'); ?> <a href="<?php $this->options->siteUrl(); ?>"><?php $this->options->title(); ?></a>.
<?php _e('由 <a href="http://www.typecho.org">Typecho</a> 强力驱动'); ?>.
<?php _e('由 <a href="https://typecho.org">Typecho</a> 强力驱动'); ?>.
</footer><!-- end #footer -->
<?php $this->footer(); ?>

View File

@ -55,7 +55,7 @@
<?php endif; ?>
<li><a href="<?php $this->options->feedUrl(); ?>"><?php _e('文章 RSS'); ?></a></li>
<li><a href="<?php $this->options->commentsFeedUrl(); ?>"><?php _e('评论 RSS'); ?></a></li>
<li><a href="http://www.typecho.org">Typecho</a></li>
<li><a href="https://typecho.org">Typecho</a></li>
</ul>
</section>
<?php endif; ?>

View File

@ -168,7 +168,7 @@ namespace Typecho {
class Common
{
/** 程序版本 */
public const VERSION = '1.2.0';
public const VERSION = '1.2.1';
/**
* 将路径转化为链接

View File

@ -47,19 +47,30 @@ class Mysqli implements Adapter
*/
public function connect(Config $config): \mysqli
{
$mysqli = mysqli_init();
if ($mysqli) {
if (!empty($config->sslCa)) {
$mysqli->ssl_set(null, null, $config->sslCa, null, null);
if (
$this->dbLink = @mysqli_connect(
if (isset($config->sslVerify)) {
$mysqli->options(MYSQLI_OPT_SSL_VERIFY_SERVER_CERT, $config->sslVerify);
}
}
$mysqli->real_connect(
$config->host,
$config->user,
$config->password,
$config->database,
(empty($config->port) ? null : $config->port)
)
) {
);
$this->dbLink = $mysqli;
if ($config->charset) {
$this->dbLink->query("SET NAMES '{$config->charset}'");
}
return $this->dbLink;
}

View File

@ -51,11 +51,22 @@ class Mysql extends Pdo
*/
public function init(Config $config): \PDO
{
$options = [];
if (!empty($config->sslCa)) {
$options[\PDO::MYSQL_ATTR_SSL_CA] = $config->sslCa;
if (isset($config->sslVerify)) {
// FIXME: https://github.com/php/php-src/issues/8577
$options[\PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT] = $config->sslVerify;
}
}
$pdo = new \PDO(
!empty($config->dsn)
? $config->dsn : "mysql:dbname={$config->database};host={$config->host};port={$config->port}",
$config->user,
$config->password
$config->password,
$options
);
$pdo->setAttribute(\PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);

View File

@ -19,6 +19,8 @@ class Request
private const FILTERS = [
'int' => 'intval',
'integer' => 'intval',
'encode' => 'urlencode',
'html' => 'htmlspecialchars',
'search' => ['\Typecho\Common', 'filterSearchQuery'],
'xss' => ['\Typecho\Common', 'removeXSS'],
'url' => ['\Typecho\Common', 'safeUrl'],
@ -83,7 +85,7 @@ class Request
}
/**
* 设置过滤器
* Add filter to request
*
* @param string|callable ...$filters
* @return $this
@ -91,8 +93,10 @@ class Request
public function filter(...$filters): Request
{
foreach ($filters as $filter) {
$this->filter[] = is_string($filter) && isset(self::FILTERS[$filter])
? self::FILTERS[$filter] : $filter;
$this->filter[] = $this->wrapFilter(
is_string($filter) && isset(self::FILTERS[$filter])
? self::FILTERS[$filter] : $filter
);
}
return $this;
@ -344,4 +348,18 @@ class Request
return $value;
}
/**
* Wrap a filter to make sure it always receives a string.
*
* @param callable $filter
*
* @return callable
*/
private function wrapFilter(callable $filter): callable
{
return function ($value) use ($filter) {
return call_user_func($filter, $value ?? '');
};
}
}

View File

@ -47,7 +47,7 @@ class Ajax extends BaseOptions implements ActionInterface
$result = ['available' => 0];
try {
$client->send('http://typecho.org/version.json');
$client->send('https://typecho.org/version.json');
/** 匹配内容体 */
$response = $client->getResponseBody();
@ -65,7 +65,7 @@ class Ajax extends BaseOptions implements ActionInterface
'available' => 1,
'latest' => $json['release'],
'current' => $version,
'link' => 'http://typecho.org/download'
'link' => 'https://typecho.org/download'
];
}
}
@ -92,7 +92,7 @@ class Ajax extends BaseOptions implements ActionInterface
if ($client) {
$client->setHeader('User-Agent', $this->options->generator)
->setTimeout(10)
->send('http://typecho.org/feed/');
->send('https://typecho.org/feed/');
/** 匹配内容体 */
$response = $client->getResponseBody();

View File

@ -531,7 +531,7 @@ class Archive extends Contents
/** 处理搜索结果跳转 */
if (isset($this->request->s)) {
$filterKeywords = $this->request->filter('search')->s;
$filterKeywords = $this->request->filter('search')->get('s');
/** 跳转到搜索页 */
if (null != $filterKeywords) {

View File

@ -268,7 +268,7 @@ class Comments extends Base implements QueryInterface
$noFollow = (null === $noFollow) ? $this->options->commentsUrlNofollow : $noFollow;
if ($this->url && $autoLink) {
echo '<a href="' . $this->url . '"'
echo '<a href="' . Common::safeUrl($this->url) . '"'
. ($noFollow ? ' rel="external nofollow"' : null) . '>' . $this->author . '</a>';
} else {
echo $this->author;

View File

@ -206,7 +206,7 @@ class Feedback extends Comments implements ActionInterface
/** Anti-XSS */
$comment['author'] = $this->request->filter('trim')->author;
$comment['mail'] = $this->request->filter('trim')->mail;
$comment['url'] = $this->request->filter('trim')->url;
$comment['url'] = $this->request->filter('trim', 'url')->url;
/** 修正用户提交的url */
if (!empty($comment['url'])) {
@ -305,7 +305,7 @@ class Feedback extends Comments implements ActionInterface
];
$trackback['author'] = $this->request->filter('trim')->blog_name;
$trackback['url'] = $this->request->filter('trim')->url;
$trackback['url'] = $this->request->filter('trim', 'url')->url;
$trackback['text'] = $this->request->excerpt;
//检验格式

View File

@ -127,10 +127,10 @@ class Menu extends Base
$panelTable = unserialize($this->options->panelTable);
$extendingParentMenu = empty($panelTable['parent']) ? [] : $panelTable['parent'];
$extendingChildMenu = empty($panelTable['child']) ? [] : $panelTable['child'];
$currentUrl = $this->request->makeUriByRequest();
$currentUrl = $this->request->getRequestUrl();
$adminUrl = $this->options->adminUrl;
$menu = [];
$defaultChildeNode = [null, null, null, 'administrator', false, null];
$defaultChildNode = [null, null, null, 'administrator', false, null];
$currentUrlParts = parse_url($currentUrl);
$currentUrlParams = [];
@ -158,7 +158,7 @@ class Menu extends Base
foreach ($childNodes[$key] as $inKey => $childNode) {
// magic merge
$childNode += $defaultChildeNode;
$childNode += $defaultChildNode;
[$name, $title, $url, $access] = $childNode;
$hidden = $childNode[4] ?? false;
@ -255,7 +255,7 @@ class Menu extends Base
}
$this->menu = $menu;
$this->currentUrl = $currentUrl;
$this->currentUrl = Common::safeUrl($currentUrl);
}
/**

View File

@ -82,7 +82,7 @@ if (!defined('__TYPECHO_ROOT_DIR__')) {
* @property bool $commentsRequireModeration
* @property bool $commentsWhitelist
* @property bool $commentsRequireMail
* @property bool $commentsRequireURL
* @property bool $commentsRequireUrl
* @property bool $commentsCheckReferer
* @property bool $commentsAntiSpam
* @property bool $commentsAutoClose

View File

@ -127,7 +127,7 @@ class Discussion extends Options implements ActionInterface
$this->options->commentDateFormat,
_t('评论日期格式'),
_t('这是一个默认的格式,当你在模板中调用显示评论日期方法时, 如果没有指定日期格式, 将按照此格式输出.') . '<br />'
. _t('具体写法请参考 <a href="http://www.php.net/manual/zh/function.date.php">PHP 日期格式写法</a>.')
. _t('具体写法请参考 <a href="https://www.php.net/manual/zh/function.date.php">PHP 日期格式写法</a>.')
);
$commentDateFormat->input->setAttribute('class', 'w-40 mono');
$form->addInput($commentDateFormat);
@ -147,8 +147,8 @@ class Discussion extends Options implements ActionInterface
'commentsShowCommentOnly' => _t('仅显示评论, 不显示 Pingback 和 Trackback'),
'commentsMarkdown' => _t('在评论中使用 Markdown 语法'),
'commentsShowUrl' => _t('评论者名称显示时自动加上其个人主页链接'),
'commentsUrlNofollow' => _t('对评论者个人主页链接使用 <a href="http://en.wikipedia.org/wiki/Nofollow">nofollow 属性</a>'),
'commentsAvatar' => _t('启用 <a href="http://gravatar.com">Gravatar</a> 头像服务, 最高显示评级为 %s 的头像',
'commentsUrlNofollow' => _t('对评论者个人主页链接使用 <a href="https://en.wikipedia.org/wiki/Nofollow">nofollow 属性</a>'),
'commentsAvatar' => _t('启用 <a href="https://gravatar.com">Gravatar</a> 头像服务, 最高显示评级为 %s 的头像',
'</label><select id="commentsShow-commentsAvatarRating" name="commentsAvatarRating">
<option value="G"' . ('G' == $this->options->commentsAvatarRating ? ' selected="true"' : '') . '>' . _t('G - 普通') . '</option>
<option value="PG"' . ('PG' == $this->options->commentsAvatarRating ? ' selected="true"' : '') . '>' . _t('PG - 13岁以上') . '</option>

View File

@ -105,7 +105,7 @@ class Reading extends Permalink
_t('文章日期格式'),
_t('此格式用于指定显示在文章归档中的日期默认显示格式.') . '<br />'
. _t('在某些主题中这个格式可能不会生效, 因为主题作者可以自定义日期格式.') . '<br />'
. _t('请参考 <a href="http://www.php.net/manual/zh/function.date.php">PHP 日期格式写法</a>.')
. _t('请参考 <a href="https://www.php.net/manual/zh/function.date.php">PHP 日期格式写法</a>.')
);
$postDateFormat->input->setAttribute('class', 'w-40 mono');
$form->addInput($postDateFormat->addRule('xssCheck', _t('请不要在日期格式中使用特殊字符')));

View File

@ -155,7 +155,7 @@ class Edit extends Users implements ActionInterface
],
null,
_t('用户组'),
_t('不同的用户组拥有不同的权限.') . '<br />' . _t('具体的权限分配表请<a href="http://docs.typecho.org/develop/acl">参考这里</a>.')
_t('不同的用户组拥有不同的权限.') . '<br />' . _t('具体的权限分配表请<a href="https://docs.typecho.org/develop/acl">参考这里</a>.')
);
$form->addInput($group);

View File

@ -53,7 +53,7 @@ class Profile extends Edit implements ActionInterface
['0' => _t('关闭'), '1' => _t('打开')],
$this->options->markdown,
_t('使用 Markdown 语法编辑和解析内容'),
_t('使用 <a href="http://daringfireball.net/projects/markdown/">Markdown</a> 语法能够使您的撰写过程更加简便直观.')
_t('使用 <a href="https://daringfireball.net/projects/markdown/">Markdown</a> 语法能够使您的撰写过程更加简便直观.')
. '<br />' . _t('此功能开启不会影响以前没有使用 Markdown 语法编辑的内容.')
);
$form->addInput($markdown);
@ -63,7 +63,7 @@ class Profile extends Edit implements ActionInterface
['0' => _t('关闭'), '1' => _t('打开')],
$this->options->xmlrpcMarkdown,
_t('在 XMLRPC 接口中使用 Markdown 语法'),
_t('对于完全支持 <a href="http://daringfireball.net/projects/markdown/">Markdown</a> 语法写作的离线编辑器, 打开此选项后将避免内容被转换为 HTML.')
_t('对于完全支持 <a href="https://daringfireball.net/projects/markdown/">Markdown</a> 语法写作的离线编辑器, 打开此选项后将避免内容被转换为 HTML.')
);
$form->addInput($xmlrpcMarkdown);