From bac7340c2aac9066ef4645dba7c64691a90b7a42 Mon Sep 17 00:00:00 2001 From: joyqi Date: Mon, 16 Aug 2021 18:34:25 +0800 Subject: [PATCH 01/12] improve installation --- admin/header.php | 1 - install.php | 269 +++++++++++++++++++++++++++++++++++++--- install/Mysql.php | 200 ++++++----------------------- install/Pgsql.php | 28 ++--- install/SQLite.php | 8 +- var/Typecho/Request.php | 232 +++++++++++++++++++--------------- var/Widget/Init.php | 4 +- var/Widget/Options.php | 43 ++++--- 8 files changed, 467 insertions(+), 318 deletions(-) diff --git a/admin/header.php b/admin/header.php index 1b5062ca..99ce79bf 100644 --- a/admin/header.php +++ b/admin/header.php @@ -18,7 +18,6 @@ $header = Typecho_Plugin::factory('admin/header.php')->header($header); - <?php _e('%s - %s - Powered by Typecho', $menu->title, $options->title); ?> diff --git a/install.php b/install.php index c464e39e..703f6cda 100644 --- a/install.php +++ b/install.php @@ -44,7 +44,246 @@ else: endif; -ob_start(); +define('__TYPECHO_INSTALL__', true); + +/** + * 获取系统语言 + * + * @return string + */ +function install_get_lang(): string { + if (isset($_SERVER['TYPECHO_LANG'])) { + return $_SERVER['TYPECHO_LANG']; + } else { + $lang = 'zh_CN'; + $request = Typecho_Request::getInstance(); + + if ($request->is('lang')) { + $lang = $request->get('lang'); + Typecho_Cookie::set('lang', $lang); + } + + return Typecho_Cookie::get('lang', $lang); + } +} + +/** + * 获取站点地址 + * + * @return string + */ +function install_get_site_url(): string { + if (isset($_SERVER['TYPECHO_SITE_URL'])) { + return $_SERVER['TYPECHO_SITE_URL']; + } else { + $request = Typecho_Request::getInstance(); + return $request->get('userUrl', $request->getRequestRoot()); + } +} + +/** + * 获取默认参数 + * + * @return array + */ +function install_get_default_options(): array { + return [ + 'theme' => 'default', + 'theme:default' => 'a:2:{s:7:"logoUrl";N;s:12:"sidebarBlock";a:5:{i:0;s:15:"ShowRecentPosts";i:1;s:18:"ShowRecentComments";i:2;s:12:"ShowCategory";i:3;s:11:"ShowArchive";i:4;s:9:"ShowOther";}}', + 'timezone' => '28800', + 'lang' => install_get_lang(), + 'charset' => _('UTF-8'), + 'contentType' => 'text/html', + 'gzip' => 0, + 'generator' => 'Typecho ' . Typecho_Common::VERSION, + 'title' => 'Hello World', + 'description' => 'Your description here.', + 'keywords' => 'typecho,php,blog', + 'rewrite' => 0, + 'frontPage' => 'recent', + 'frontArchive' => 0, + 'commentsRequireMail' => 1, + 'commentsWhitelist' => 0, + 'commentsRequireURL' => 0, + 'commentsRequireModeration' => 0, + 'plugins' => 'a:0:{}', + 'commentDateFormat' => 'F jS, Y \a\t h:i a', + 'siteUrl' => install_get_site_url(), + 'defaultCategory' => 1, + 'allowRegister' => 0, + 'defaultAllowComment' => 1, + 'defaultAllowPing' => 1, + 'defaultAllowFeed' => 1, + 'pageSize' => 5, + 'postsListSize' => 10, + 'commentsListSize' => 10, + 'commentsHTMLTagAllowed' => null, + 'postDateFormat' => 'Y-m-d', + 'feedFullText' => 1, + 'editorSize' => 350, + 'autoSave' => 0, + 'markdown' => 1, + 'xmlrpcMarkdown' => 0, + 'commentsMaxNestingLevels' => 5, + 'commentsPostTimeout' => 24 * 3600 * 30, + 'commentsUrlNofollow' => 1, + 'commentsShowUrl' => 1, + 'commentsMarkdown' => 0, + 'commentsPageBreak' => 0, + 'commentsThreaded' => 1, + 'commentsPageSize' => 20, + 'commentsPageDisplay' => 'last', + 'commentsOrder' => 'ASC', + 'commentsCheckReferer' => 1, + 'commentsAutoClose' => 0, + 'commentsPostIntervalEnable' => 1, + 'commentsPostInterval' => 60, + 'commentsShowCommentOnly' => 0, + 'commentsAvatar' => 1, + 'commentsAvatarRating' => 'G', + 'commentsAntiSpam' => 1, + 'routingTable' => 'a:25:{s:5:"index";a:3:{s:3:"url";s:1:"/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:7:"archive";a:3:{s:3:"url";s:6:"/blog/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:2:"do";a:3:{s:3:"url";s:22:"/action/[action:alpha]";s:6:"widget";s:9:"Widget_Do";s:6:"action";s:6:"action";}s:4:"post";a:3:{s:3:"url";s:24:"/archives/[cid:digital]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:10:"attachment";a:3:{s:3:"url";s:26:"/attachment/[cid:digital]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:8:"category";a:3:{s:3:"url";s:17:"/category/[slug]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:3:"tag";a:3:{s:3:"url";s:12:"/tag/[slug]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:6:"author";a:3:{s:3:"url";s:22:"/author/[uid:digital]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:6:"search";a:3:{s:3:"url";s:19:"/search/[keywords]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:10:"index_page";a:3:{s:3:"url";s:21:"/page/[page:digital]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:12:"archive_page";a:3:{s:3:"url";s:26:"/blog/page/[page:digital]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:13:"category_page";a:3:{s:3:"url";s:32:"/category/[slug]/[page:digital]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:8:"tag_page";a:3:{s:3:"url";s:27:"/tag/[slug]/[page:digital]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:11:"author_page";a:3:{s:3:"url";s:37:"/author/[uid:digital]/[page:digital]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:11:"search_page";a:3:{s:3:"url";s:34:"/search/[keywords]/[page:digital]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:12:"archive_year";a:3:{s:3:"url";s:18:"/[year:digital:4]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:13:"archive_month";a:3:{s:3:"url";s:36:"/[year:digital:4]/[month:digital:2]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:11:"archive_day";a:3:{s:3:"url";s:52:"/[year:digital:4]/[month:digital:2]/[day:digital:2]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:17:"archive_year_page";a:3:{s:3:"url";s:38:"/[year:digital:4]/page/[page:digital]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:18:"archive_month_page";a:3:{s:3:"url";s:56:"/[year:digital:4]/[month:digital:2]/page/[page:digital]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:16:"archive_day_page";a:3:{s:3:"url";s:72:"/[year:digital:4]/[month:digital:2]/[day:digital:2]/page/[page:digital]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:12:"comment_page";a:3:{s:3:"url";s:53:"[permalink:string]/comment-page-[commentPage:digital]";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:4:"feed";a:3:{s:3:"url";s:20:"/feed[feed:string:0]";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:4:"feed";}s:8:"feedback";a:3:{s:3:"url";s:31:"[permalink:string]/[type:alpha]";s:6:"widget";s:15:"Widget_Feedback";s:6:"action";s:6:"action";}s:4:"page";a:3:{s:3:"url";s:12:"/[slug].html";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}}', + 'actionTable' => 'a:0:{}', + 'panelTable' => 'a:0:{}', + 'attachmentTypes' => '@image@', + 'secret' => Typecho_Common::randString(32, true), + 'installed' => 0, + 'allowXmlRpc' => 2 + ]; +} + +/** + * 获取所有可用数据库驱动 + * + * @return array + */ +function install_get_db_drivers(): array { + $drivers = []; + + if (Typecho_Db_Adapter_Mysqli::isAvailable()) { + $drivers['Mysqli'] = _t('Mysql 原生函数适配器'); + } + + if (Typecho_Db_Adapter_SQLite::isAvailable()) { + $drivers['SQLite'] = _t('SQLite 原生函数适配器 (SQLite 2.x)'); + } + + if (Typecho_Db_Adapter_Pgsql::isAvailable()) { + $drivers['Pgsql'] = _t('Pgsql 原生函数适配器'); + } + + if (Typecho_Db_Adapter_Pdo_Mysql::isAvailable()) { + $drivers['Pdo_Mysql'] = _t('Pdo 驱动 Mysql 适配器'); + } + + if (Typecho_Db_Adapter_Pdo_SQLite::isAvailable()) { + $drivers['Pdo_SQLite'] = _t('Pdo 驱动 SQLite 适配器 (SQLite 3.x)'); + } + + if (Typecho_Db_Adapter_Pdo_Pgsql::isAvailable()) { + $drivers['Pdo_Pgsql'] = _t('Pdo 驱动 PostgreSql 适配器'); + } + + return $drivers; +} + +function install_ajax_support() { +?> + + +
+

+

+

+

+

GPL 协议发布, 我们允许用户在 GPL 协议许可的范围内使用, 拷贝, 修改和分发此程序.'); ?> +

+

+ +

+

+ + + 1): ?> + + +

+
+ + +get($name, $default); } /** @@ -96,9 +335,8 @@ function _rFrom() { * * @param string $name 参数名称 * @param string $default 默认值 - * @return string */ -function _v($name, $default = '') { +function _v(string $name, string $default = '') { echo _r($name, $default); } @@ -145,12 +383,12 @@ function _u() { $options = new stdClass(); $options->generator = 'Typecho ' . Typecho_Common::VERSION; -list($soft, $currentVersion) = explode(' ', $options->generator); +[$soft, $currentVersion] = explode(' ', $options->generator); $options->software = $soft; $options->version = $currentVersion; -list($prefixVersion, $suffixVersion) = explode('/', $currentVersion); +[$prefixVersion, $suffixVersion] = explode('/', $currentVersion); /** 获取语言 */ $lang = _r('lang', Typecho_Cookie::get('__typecho_lang')); @@ -167,10 +405,11 @@ if ('zh_CN' != $lang) { Typecho_Cookie::set('__typecho_lang', $lang); ?> - - + + - <?php _e('Typecho 安装程序'); ?> + + <?php _e('Typecho 安装程序'); ?> @@ -221,10 +460,6 @@ Typecho_Cookie::set('__typecho_lang', $lang); -
- 参与用户调查, 帮助我们完善产品 -
-

:

addRule('dbAdapter', 'required', _t('确认您的配置')) ->addRule('dbAdapter', 'enum', _t('确认您的配置'), array_keys($drivers)) ->addRule('dbNext', 'required', _t('确认您的配置')) - ->addRule('dbNext', 'enum', _t('确认您的配置'), ['none', 'delete', 'keep']) + ->addRule('dbNext', 'enum', _t('确认您的配置'), ['none', 'delete', 'keep', 'config']) ->run($config); if (!empty($error)) { @@ -749,7 +768,11 @@ function install_step_2_perform() { $dbConfig[strtolower(substr($key, 2))] = $config[$key]; } - if (empty($installDb)) { + // check config file + if ($config['dbNext'] == 'config' && !install_check('config')) { + $code = install_config_file($config['dbAdapter'], $config['dbPrefix'], $dbConfig, true); + install_raise_error(_t('没有检测到您手动创建的配置文件, 请检查后再次创建'), ['code' => $code]); + } elseif (empty($installDb)) { // detect db config try { $installDb = new Typecho_Db($config['dbAdapter'], $config['dbPrefix']); @@ -862,18 +885,18 @@ function install_step_3() {

- + @@ -887,7 +910,7 @@ function install_step_3() { @@ -901,7 +924,7 @@ function install_step_3() { $request->getServer('TYPECHO_SITE_URL', 'http://localhost'), + 'userUrl' => $request->getServer('TYPECHO_SITE_URL'), 'userName' => $request->getServer('TYPECHO_USER_NAME', 'typecho'), 'userPassword' => $request->getServer('TYPECHO_USER_PASSWORD'), 'userMail' => $request->getServer('TYPECHO_USER_MAIL', 'admin@localhost.local') @@ -931,12 +954,13 @@ function install_step_3_perform() { } $error = (new Typecho_Validate()) - ->addRule('userUrl', 'required', _t('请填写您的网站地址')) - ->addRule('userUrl', 'url', _t('请填写您的网站地址')) - ->addRule('userName', 'required', _t('请填写您的用户名')) + ->addRule('userUrl', 'required', _t('请填写站点地址')) + ->addRule('userUrl', 'url', _t('请填写一个合法的URL地址')) + ->addRule('userName', 'required', _t('必须填写用户名称')) + ->addRule('userName', 'xssCheck', _t('请不要在用户名中使用特殊字符')) ->addRule('userName', 'maxLength', _t('用户名长度超过限制, 请不要超过 32 个字符'), 32) - ->addRule('userMail', 'required', _t('请填写您的邮箱地址')) - ->addRule('userMail', 'email', _t('请填写您的邮箱地址')) + ->addRule('userMail', 'required', _t('必须填写电子邮箱')) + ->addRule('userMail', 'email', _t('电子邮箱格式错误')) ->addRule('userMail', 'maxLength', _t('邮箱长度超过限制, 请不要超过 200 个字符'), 200) ->run($config); @@ -1039,9 +1063,19 @@ function install_step_3_perform() { install_raise_error($e->getMessage()); } + $parts = parse_url($options->loginAction); + $parts['query'] = http_build_query([ + 'name' => $config['userName'], + 'password' => $config['userPassword'], + 'referer' => $options->adminUrl + ]); + $loginUrl = Typecho_Common::buildUrl($parts); + install_success(0, [ $config['userName'], - $config['userPassword'] + $config['userPassword'], + Typecho_Widget::widget('Widget_Security')->getTokenUrl($loginUrl, $request->getReferer()), + $options->siteUrl ]); } @@ -1117,6 +1151,7 @@ function install_dispatch() { +
@@ -1130,608 +1165,3 @@ function install_dispatch() { } install_dispatch(); -exit; - -// 挡掉可能的跨站请求 -if (!empty($_GET) || !empty($_POST)) { - if (empty($_SERVER['HTTP_REFERER'])) { - exit; - } - - $parts = parse_url($_SERVER['HTTP_REFERER']); - if (!empty($parts['port'])) { - $parts['host'] = "{$parts['host']}:{$parts['port']}"; - } - - if (empty($parts['host']) || $_SERVER['HTTP_HOST'] != $parts['host']) { - exit; - } -} - -/** - * 获取传递参数 - * - * @param string $name 参数名称 - * @param string|null $default 默认值 - * - * @return mixed - */ -function _r(string $name, string $default = NULL) { - return Typecho_Request::getInstance()->get($name, $default); -} - -/** - * 获取多个传递参数 - * - * @return array - */ -function _rFrom() { - $result = array(); - $params = func_get_args(); - - foreach ($params as $param) { - $result[$param] = isset($_REQUEST[$param]) ? - (is_array($_REQUEST[$param]) ? NULL : $_REQUEST[$param]) : NULL; - } - - return $result; -} - -/** - * 输出传递参数 - * - * @param string $name 参数名称 - * @param string $default 默认值 - */ -function _v(string $name, string $default = '') { - echo _r($name, $default); -} - -/** - * 判断是否兼容某个环境(perform) - * - * @param string $adapter 适配器 - * @return boolean - */ -function _p($adapter) { - switch ($adapter) { - case 'Mysql': - return Typecho_Db_Adapter_Mysql::isAvailable(); - case 'Mysqli': - return Typecho_Db_Adapter_Mysqli::isAvailable(); - case 'Pdo_Mysql': - return Typecho_Db_Adapter_Pdo_Mysql::isAvailable(); - case 'SQLite': - return Typecho_Db_Adapter_SQLite::isAvailable(); - case 'Pdo_SQLite': - return Typecho_Db_Adapter_Pdo_SQLite::isAvailable(); - case 'Pgsql': - return Typecho_Db_Adapter_Pgsql::isAvailable(); - case 'Pdo_Pgsql': - return Typecho_Db_Adapter_Pdo_Pgsql::isAvailable(); - default: - return false; - } -} - -/** - * 获取url地址 - * - * @return string - */ -function _u() { - $url = Typecho_Request::getUrlPrefix() . $_SERVER['REQUEST_URI']; - if (isset($_SERVER['QUERY_STRING'])) { - $url = str_replace('?' . $_SERVER['QUERY_STRING'], '', $url); - } - - return dirname($url); -} - -$options = new stdClass(); -$options->generator = 'Typecho ' . Typecho_Common::VERSION; -[$soft, $currentVersion] = explode(' ', $options->generator); - -$options->software = $soft; -$options->version = $currentVersion; - -[$prefixVersion, $suffixVersion] = explode('/', $currentVersion); - -/** 获取语言 */ -$lang = _r('lang', Typecho_Cookie::get('__typecho_lang')); -$langs = Widget_Options_General::getLangs(); - -if (empty($lang) || (!empty($langs) && !isset($langs[$lang]))) { - $lang = 'zh_CN'; -} - -if ('zh_CN' != $lang) { - $dir = defined('__TYPECHO_LANG_DIR__') ? __TYPECHO_LANG_DIR__ : __TYPECHO_ROOT_DIR__ . '/usr/langs'; - Typecho_I18n::setLang($dir . '/' . $lang . '.mo'); -} - -Typecho_Cookie::set('__typecho_lang', $lang); -?> - - - - - <?php _e('Typecho 安装程序'); ?> - - - - - -
-

Typecho

-
    - class="current">1 - class="current">2 - class="current">3 - class="current">4 -
-
-
-
-
-
- - -

-
- -

- -
- -

-
-
-

-
-
- - query($db->update('table.options')->rows(['value' => 1])->where('name = ?', 'installed')); - ?> -

-
-
- - - - - :
- : - - -
- -
-

:

-
    - getTokenUrl($loginUrl); - } else { - $loginUrl = _u() . '/admin/index.php'; - } - ?> -
  • -
  • -
-
- -

-
- - - -

-
-
-

-
-
- - query($script, Typecho_Db::WRITE); - } - } - - /** 全局变量 */ - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'theme', 'user' => 0, 'value' => 'default'))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'theme:default', 'user' => 0, 'value' => 'a:2:{s:7:"logoUrl";N;s:12:"sidebarBlock";a:5:{i:0;s:15:"ShowRecentPosts";i:1;s:18:"ShowRecentComments";i:2;s:12:"ShowCategory";i:3;s:11:"ShowArchive";i:4;s:9:"ShowOther";}}'))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'timezone', 'user' => 0, 'value' => _t('28800')))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'lang', 'user' => 0, 'value' => $lang))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'charset', 'user' => 0, 'value' => _t('UTF-8')))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'contentType', 'user' => 0, 'value' => 'text/html'))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'gzip', 'user' => 0, 'value' => 0))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'generator', 'user' => 0, 'value' => $options->generator))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'title', 'user' => 0, 'value' => 'Hello World'))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'description', 'user' => 0, 'value' => 'Just So So ...'))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'keywords', 'user' => 0, 'value' => 'typecho,php,blog'))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'rewrite', 'user' => 0, 'value' => 0))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'frontPage', 'user' => 0, 'value' => 'recent'))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'frontArchive', 'user' => 0, 'value' => 0))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'commentsRequireMail', 'user' => 0, 'value' => 1))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'commentsWhitelist', 'user' => 0, 'value' => 0))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'commentsRequireURL', 'user' => 0, 'value' => 0))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'commentsRequireModeration', 'user' => 0, 'value' => 0))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'plugins', 'user' => 0, 'value' => 'a:0:{}'))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'commentDateFormat', 'user' => 0, 'value' => 'F jS, Y \a\t h:i a'))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'siteUrl', 'user' => 0, 'value' => $config['siteUrl']))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'defaultCategory', 'user' => 0, 'value' => 1))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'allowRegister', 'user' => 0, 'value' => 0))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'defaultAllowComment', 'user' => 0, 'value' => 1))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'defaultAllowPing', 'user' => 0, 'value' => 1))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'defaultAllowFeed', 'user' => 0, 'value' => 1))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'pageSize', 'user' => 0, 'value' => 5))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'postsListSize', 'user' => 0, 'value' => 10))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'commentsListSize', 'user' => 0, 'value' => 10))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'commentsHTMLTagAllowed', 'user' => 0, 'value' => NULL))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'postDateFormat', 'user' => 0, 'value' => 'Y-m-d'))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'feedFullText', 'user' => 0, 'value' => 1))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'editorSize', 'user' => 0, 'value' => 350))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'autoSave', 'user' => 0, 'value' => 0))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'markdown', 'user' => 0, 'value' => 1))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'xmlrpcMarkdown', 'user' => 0, 'value' => 0))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'commentsMaxNestingLevels', 'user' => 0, 'value' => 5))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'commentsPostTimeout', 'user' => 0, 'value' => 24 * 3600 * 30))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'commentsUrlNofollow', 'user' => 0, 'value' => 1))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'commentsShowUrl', 'user' => 0, 'value' => 1))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'commentsMarkdown', 'user' => 0, 'value' => 0))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'commentsPageBreak', 'user' => 0, 'value' => 0))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'commentsThreaded', 'user' => 0, 'value' => 1))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'commentsPageSize', 'user' => 0, 'value' => 20))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'commentsPageDisplay', 'user' => 0, 'value' => 'last'))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'commentsOrder', 'user' => 0, 'value' => 'ASC'))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'commentsCheckReferer', 'user' => 0, 'value' => 1))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'commentsAutoClose', 'user' => 0, 'value' => 0))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'commentsPostIntervalEnable', 'user' => 0, 'value' => 1))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'commentsPostInterval', 'user' => 0, 'value' => 60))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'commentsShowCommentOnly', 'user' => 0, 'value' => 0))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'commentsAvatar', 'user' => 0, 'value' => 1))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'commentsAvatarRating', 'user' => 0, 'value' => 'G'))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'commentsAntiSpam', 'user' => 0, 'value' => 1))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'routingTable', 'user' => 0, 'value' => 'a:25:{s:5:"index";a:3:{s:3:"url";s:1:"/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:7:"archive";a:3:{s:3:"url";s:6:"/blog/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:2:"do";a:3:{s:3:"url";s:22:"/action/[action:alpha]";s:6:"widget";s:9:"Widget_Do";s:6:"action";s:6:"action";}s:4:"post";a:3:{s:3:"url";s:24:"/archives/[cid:digital]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:10:"attachment";a:3:{s:3:"url";s:26:"/attachment/[cid:digital]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:8:"category";a:3:{s:3:"url";s:17:"/category/[slug]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:3:"tag";a:3:{s:3:"url";s:12:"/tag/[slug]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:6:"author";a:3:{s:3:"url";s:22:"/author/[uid:digital]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:6:"search";a:3:{s:3:"url";s:19:"/search/[keywords]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:10:"index_page";a:3:{s:3:"url";s:21:"/page/[page:digital]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:12:"archive_page";a:3:{s:3:"url";s:26:"/blog/page/[page:digital]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:13:"category_page";a:3:{s:3:"url";s:32:"/category/[slug]/[page:digital]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:8:"tag_page";a:3:{s:3:"url";s:27:"/tag/[slug]/[page:digital]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:11:"author_page";a:3:{s:3:"url";s:37:"/author/[uid:digital]/[page:digital]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:11:"search_page";a:3:{s:3:"url";s:34:"/search/[keywords]/[page:digital]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:12:"archive_year";a:3:{s:3:"url";s:18:"/[year:digital:4]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:13:"archive_month";a:3:{s:3:"url";s:36:"/[year:digital:4]/[month:digital:2]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:11:"archive_day";a:3:{s:3:"url";s:52:"/[year:digital:4]/[month:digital:2]/[day:digital:2]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:17:"archive_year_page";a:3:{s:3:"url";s:38:"/[year:digital:4]/page/[page:digital]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:18:"archive_month_page";a:3:{s:3:"url";s:56:"/[year:digital:4]/[month:digital:2]/page/[page:digital]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:16:"archive_day_page";a:3:{s:3:"url";s:72:"/[year:digital:4]/[month:digital:2]/[day:digital:2]/page/[page:digital]/";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:12:"comment_page";a:3:{s:3:"url";s:53:"[permalink:string]/comment-page-[commentPage:digital]";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}s:4:"feed";a:3:{s:3:"url";s:20:"/feed[feed:string:0]";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:4:"feed";}s:8:"feedback";a:3:{s:3:"url";s:31:"[permalink:string]/[type:alpha]";s:6:"widget";s:15:"Widget_Feedback";s:6:"action";s:6:"action";}s:4:"page";a:3:{s:3:"url";s:12:"/[slug].html";s:6:"widget";s:14:"Widget_Archive";s:6:"action";s:6:"render";}}'))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'actionTable', 'user' => 0, 'value' => 'a:0:{}'))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'panelTable', 'user' => 0, 'value' => 'a:0:{}'))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'attachmentTypes', 'user' => 0, 'value' => '@image@'))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'secret', 'user' => 0, 'value' => Typecho_Common::randString(32, true)))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'installed', 'user' => 0, 'value' => 0))); - $installDb->query($installDb->insert('table.options')->rows(array('name' => 'allowXmlRpc', 'user' => 0, 'value' => 2))); - - /** 初始分类 */ - $installDb->query($installDb->insert('table.metas')->rows(array('name' => _t('默认分类'), 'slug' => 'default', 'type' => 'category', 'description' => _t('只是一个默认分类'), - 'count' => 1, 'order' => 1))); - - /** 初始关系 */ - $installDb->query($installDb->insert('table.relationships')->rows(array('cid' => 1, 'mid' => 1))); - - /** 初始内容 */ - $installDb->query($installDb->insert('table.contents')->rows(array('title' => _t('欢迎使用 Typecho'), 'slug' => 'start', 'created' => Typecho_Date::time(), 'modified' => Typecho_Date::time(), - 'text' => '' . _t('如果您看到这篇文章,表示您的 blog 已经安装成功.'), 'authorId' => 1, 'type' => 'post', 'status' => 'publish', 'commentsNum' => 1, 'allowComment' => 1, - 'allowPing' => 1, 'allowFeed' => 1, 'parent' => 0))); - - $installDb->query($installDb->insert('table.contents')->rows(array('title' => _t('关于'), 'slug' => 'start-page', 'created' => Typecho_Date::time(), 'modified' => Typecho_Date::time(), - 'text' => '' . _t('本页面由 Typecho 创建, 这只是个测试页面.'), 'authorId' => 1, 'order' => 0, 'type' => 'page', 'status' => 'publish', 'commentsNum' => 0, 'allowComment' => 1, - 'allowPing' => 1, 'allowFeed' => 1, 'parent' => 0))); - - /** 初始评论 */ - $installDb->query($installDb->insert('table.comments')->rows(array('cid' => 1, 'created' => Typecho_Date::time(), 'author' => 'Typecho', 'ownerId' => 1, 'url' => 'http://typecho.org', - 'ip' => '127.0.0.1', 'agent' => $options->generator, 'text' => '欢迎加入 Typecho 大家族', 'type' => 'comment', 'status' => 'approved', 'parent' => 0))); - - /** 初始用户 */ - $password = empty($config['userPassword']) ? substr(uniqid(), 7) : $config['userPassword']; - $hasher = new PasswordHash(8, true); - - $installDb->query($installDb->insert('table.users')->rows(array('name' => $config['userName'], 'password' => $hasher->HashPassword($password), 'mail' => $config['userMail'], - 'url' => 'http://www.typecho.org', 'screenName' => $config['userName'], 'group' => 'administrator', 'created' => Typecho_Date::time()))); - - unset($_SESSION['typecho']); - header('Location: ./install.php?finish&user=' . urlencode($config['userName']) - . '&password=' . urlencode($password)); - } catch (Typecho_Db_Exception $e) { - $success = false; - $code = $e->getCode(); -?> -

-
-
-query("DROP TABLE IF EXISTS `{$table}`"); - } elseif($type == 'Pgsql') { - $installDb->query("DROP TABLE {$table}"); - } elseif($type == 'SQLite') { - $installDb->query("DROP TABLE {$table}"); - } - } - echo '

' . _t('已经删除完原有数据') . '

'; - } elseif (_r('goahead')) { - //使用原有数据 - //但是要更新用户网站 - $installDb->query($installDb->update('table.options')->rows(array('value' => $config['siteUrl']))->where('name = ?', 'siteUrl')); - unset($_SESSION['typecho']); - header('Location: ./install.php?finish&use_old'); - exit; - } else { - echo '

' . _t('安装程序检查到原有数据表已经存在.') - . '

' . ' ' - . _t('或者') . '

'; - } - } else { - echo '

' . _t('安装程序捕捉到以下错误: "%s". 程序被终止, 请检查您的配置信息.',$e->getMessage()) . '

'; - } - ?> -
-
- - - - -
-

-
-

- ' . _t('没有检测到您手动创建的配置文件, 请检查后再次创建') . '

'; - $success = false; - } else { - if (NULL == _r('userUrl')) { - $success = false; - echo '

' . _t('请填写您的网站地址') . '

'; - } else if (NULL == _r('userName')) { - $success = false; - echo '

' . _t('请填写您的用户名') . '

'; - } else if (NULL == _r('userMail')) { - $success = false; - echo '

' . _t('请填写您的邮箱地址') . '

'; - } else if (32 < strlen(_r('userName'))) { - $success = false; - echo '

' . _t('用户名长度超过限制, 请不要超过 32 个字符') . '

'; - } else if (200 < strlen(_r('userMail'))) { - $success = false; - echo '

' . _t('邮箱长度超过限制, 请不要超过 200 个字符') . '

'; - } - } - - $_dbConfig = _rFrom('dbHost', 'dbUser', 'dbPassword', 'dbCharset', 'dbPort', 'dbDatabase', 'dbFile', 'dbDsn', 'dbEngine'); - - $_dbConfig = array_filter($_dbConfig); - $dbConfig = array(); - foreach ($_dbConfig as $key => $val) { - $dbConfig[strtolower(substr($key, 2))] = $val; - } - - // 在特殊服务器上的特殊安装过程处理 - if (_r('config')) { - $replace = array_keys($dbConfig); - foreach ($replace as &$key) { - $key = '{' . $key . '}'; - } - - if (!empty($_dbConfig['dbDsn'])) { - $dbConfig['dsn'] = str_replace($replace, array_values($dbConfig), $dbConfig['dsn']); - } - $config = str_replace($replace, array_values($dbConfig), _r('config')); - } - - if (!isset($config) && $success && !_r('created')) { - $installDb = new Typecho_Db($adapter, _r('dbPrefix')); - $installDb->addServer($dbConfig, Typecho_Db::READ | Typecho_Db::WRITE); - - - /** 检测数据库配置 */ - try { - $installDb->query('SELECT 1=1'); - } catch (Typecho_Db_Adapter_Exception $e) { - $success = false; - echo '

' - . _t('对不起, 无法连接数据库, 请先检查数据库配置再继续进行安装') . '

'; - } catch (Typecho_Db_Exception $e) { - $success = false; - echo '

' - . _t('安装程序捕捉到以下错误: " %s ". 程序被终止, 请检查您的配置信息.',$e->getMessage()) . '

'; - } - } - - if($success) { - // 重置原有数据库状态 - if (isset($installDb)) { - try { - $installDb->query($installDb->update('table.options') - ->rows(array('value' => 0))->where('name = ?', 'installed')); - } catch (Exception $e) { - // do nothing - } - } - - Typecho_Cookie::set('__typecho_config', base64_encode(serialize(array_merge(array( - 'prefix' => _r('dbPrefix'), - 'userName' => _r('userName'), - 'userPassword' => _r('userPassword'), - 'userMail' => _r('userMail'), - 'adapter' => $adapter, - 'siteUrl' => _r('userUrl') - ), $dbConfig)))); - - if (_r('created')) { - header('Location: ./install.php?start'); - exit; - } - - /** 初始化配置文件 */ - $lines = array_slice(file(__FILE__), 1, 26); - $lines[] = " -/** 定义数据库参数 */ -\$db = new Typecho_Db('{$adapter}', '" . _r('dbPrefix') . "'); -\$db->addServer(" . (empty($config) ? var_export($dbConfig, true) : $config) . ", Typecho_Db::READ | Typecho_Db::WRITE); -Typecho_Db::set(\$db); -"; - $contents = implode('', $lines); - if (!Typecho_Common::isAppEngine()) { - @file_put_contents('./config.inc.php', $contents); - } - - if (!file_exists('./config.inc.php')) { - ?> -

config.inc.php 文件'); ?>
-config.inc.php 文件, 并复制如下代码至其中'); ?>

-

-

- -
    -
  • - - -

    -
  • - -
  • - - -

    -
  • -
- - - -

-
    -
  • - - -

    -
  • -
  • - - -

    -
  • -
  • - - -

    -
  • -
  • - - -

    -
  • -
-
- -

-
- -
-

-
-

-

-

-

GPL 协议发布, 我们允许用户在 GPL 协议许可的范围内使用, 拷贝, 修改和分发此程序.'); ?> -

-

- -

-
-

- - - 1): ?> - - -

-
- - -
-
-
-
- diff --git a/var/Typecho/Request.php b/var/Typecho/Request.php index dca840ac..08d961d5 100644 --- a/var/Typecho/Request.php +++ b/var/Typecho/Request.php @@ -748,9 +748,9 @@ class Typecho_Request * 获取客户端 * * @access public - * @return string + * @return string|null */ - public function getReferer(): string + public function getReferer(): ?string { if (null === $this->_referer) { $this->setReferer(); diff --git a/var/Widget/Contents/Attachment/Edit.php b/var/Widget/Contents/Attachment/Edit.php index e3e09bce..2e7a4fd7 100644 --- a/var/Widget/Contents/Attachment/Edit.php +++ b/var/Widget/Contents/Attachment/Edit.php @@ -117,7 +117,7 @@ class Widget_Contents_Attachment_Edit extends Widget_Contents_Post_Edit implemen Typecho_Widget_Helper_Form::POST_METHOD); /** 文件名称 */ - $name = new Typecho_Widget_Helper_Form_Element_Text('name', NULL, $this->title, _t('标题 *')); + $name = new Typecho_Widget_Helper_Form_Element_Text('name', NULL, $this->title, _t('标题') . ' *'); $form->addInput($name); /** 文件缩略名 */ diff --git a/var/Widget/Metas/Category/Edit.php b/var/Widget/Metas/Category/Edit.php index 6ff55b3c..cb096dc5 100644 --- a/var/Widget/Metas/Category/Edit.php +++ b/var/Widget/Metas/Category/Edit.php @@ -128,7 +128,7 @@ class Widget_Metas_Category_Edit extends Widget_Abstract_Metas implements Widget Typecho_Widget_Helper_Form::POST_METHOD); /** 分类名称 */ - $name = new Typecho_Widget_Helper_Form_Element_Text('name', NULL, NULL, _t('分类名称 *')); + $name = new Typecho_Widget_Helper_Form_Element_Text('name', NULL, NULL, _t('分类名称') . ' *'); $form->addInput($name); /** 分类缩略名 */ diff --git a/var/Widget/Metas/Tag/Edit.php b/var/Widget/Metas/Tag/Edit.php index ec0f9081..6bc64d78 100644 --- a/var/Widget/Metas/Tag/Edit.php +++ b/var/Widget/Metas/Tag/Edit.php @@ -130,7 +130,7 @@ class Widget_Metas_Tag_Edit extends Widget_Abstract_Metas implements Widget_Inte /** 标签名称 */ $name = new Typecho_Widget_Helper_Form_Element_Text('name', NULL, NULL, - _t('标签名称 *'), _t('这是标签在站点中显示的名称.可以使用中文,如 "地球".')); + _t('标签名称') . ' *', _t('这是标签在站点中显示的名称.可以使用中文,如 "地球".')); $form->addInput($name); /** 标签缩略名 */ diff --git a/var/Widget/Security.php b/var/Widget/Security.php index 03e2b9b4..44c2569c 100644 --- a/var/Widget/Security.php +++ b/var/Widget/Security.php @@ -95,9 +95,10 @@ class Widget_Security extends Typecho_Widget * 生成带token的路径 * * @param $path + * @param string|null $url * @return string */ - public function getTokenUrl($path) + public function getTokenUrl($path, ?string $url = null) { $parts = parse_url($path); $params = array(); @@ -106,7 +107,7 @@ class Widget_Security extends Typecho_Widget parse_str($parts['query'], $params); } - $params['_'] = $this->getToken($this->request->getRequestUrl()); + $params['_'] = $this->getToken($url ?: $this->request->getRequestUrl()); $parts['query'] = http_build_query($params); return Typecho_Common::buildUrl($parts); diff --git a/var/Widget/Users/Edit.php b/var/Widget/Users/Edit.php index 3f8ea864..21dc934c 100644 --- a/var/Widget/Users/Edit.php +++ b/var/Widget/Users/Edit.php @@ -95,12 +95,12 @@ class Widget_Users_Edit extends Widget_Abstract_Users implements Widget_Interfac Typecho_Widget_Helper_Form::POST_METHOD); /** 用户名称 */ - $name = new Typecho_Widget_Helper_Form_Element_Text('name', NULL, NULL, _t('用户名 *'), _t('此用户名将作为用户登录时所用的名称.') + $name = new Typecho_Widget_Helper_Form_Element_Text('name', NULL, NULL, _t('用户名') . ' *', _t('此用户名将作为用户登录时所用的名称.') . '
' . _t('请不要与系统中现有的用户名重复.')); $form->addInput($name); /** 电子邮箱地址 */ - $mail = new Typecho_Widget_Helper_Form_Element_Text('mail', NULL, NULL, _t('电子邮箱地址 *'), _t('电子邮箱地址将作为此用户的主要联系方式.') + $mail = new Typecho_Widget_Helper_Form_Element_Text('mail', NULL, NULL, _t('邮件地址') . ' *', _t('电子邮箱地址将作为此用户的主要联系方式.') . '
' . _t('请不要与系统中现有的电子邮箱地址重复.')); $form->addInput($mail); @@ -180,8 +180,8 @@ class Widget_Users_Edit extends Widget_Abstract_Users implements Widget_Interfac $name->addRule('required', _t('必须填写用户名称')); $name->addRule('xssCheck', _t('请不要在用户名中使用特殊字符')); $name->addRule(array($this, 'nameExists'), _t('用户名已经存在')); - $password->label(_t('用户密码 *')); - $confirm->label(_t('用户密码确认 *')); + $password->label(_t('用户密码') . ' *'); + $confirm->label(_t('用户密码确认') . ' *'); $password->addRule('required', _t('必须填写密码')); } diff --git a/var/Widget/Users/Profile.php b/var/Widget/Users/Profile.php index c558cb4d..a579b270 100644 --- a/var/Widget/Users/Profile.php +++ b/var/Widget/Users/Profile.php @@ -55,7 +55,7 @@ class Widget_Users_Profile extends Widget_Users_Edit implements Widget_Interface $form->addInput($url); /** 电子邮箱地址 */ - $mail = new Typecho_Widget_Helper_Form_Element_Text('mail', NULL, NULL, _t('电子邮箱地址 *'), _t('电子邮箱地址将作为此用户的主要联系方式.') + $mail = new Typecho_Widget_Helper_Form_Element_Text('mail', NULL, NULL, _t('邮件地址') . ' *', _t('电子邮箱地址将作为此用户的主要联系方式.') . '
' . _t('请不要与系统中现有的电子邮箱地址重复.')); $form->addInput($mail);