2013-07-17 13:13:57 +08:00
|
|
|
<?php
|
|
|
|
|
2021-08-23 18:43:32 +08:00
|
|
|
if (!file_exists(dirname(__FILE__) . '/config.inc.php')) {
|
|
|
|
// site root path
|
|
|
|
define('__TYPECHO_ROOT_DIR__', dirname(__FILE__));
|
2013-07-17 13:13:57 +08:00
|
|
|
|
2021-08-23 18:43:32 +08:00
|
|
|
// plugin directory (relative path)
|
|
|
|
define('__TYPECHO_PLUGIN_DIR__', '/usr/plugins');
|
2013-07-17 13:13:57 +08:00
|
|
|
|
2021-08-23 18:43:32 +08:00
|
|
|
// theme directory (relative path)
|
|
|
|
define('__TYPECHO_THEME_DIR__', '/usr/themes');
|
2013-07-17 13:13:57 +08:00
|
|
|
|
2021-08-23 18:43:32 +08:00
|
|
|
// admin directory (relative path)
|
|
|
|
define('__TYPECHO_ADMIN_DIR__', '/admin/');
|
2013-07-17 13:13:57 +08:00
|
|
|
|
2021-08-23 18:43:32 +08:00
|
|
|
// register autoload
|
|
|
|
require_once __TYPECHO_ROOT_DIR__ . '/var/Typecho/Common.php';
|
2013-07-17 13:13:57 +08:00
|
|
|
|
2021-08-23 18:43:32 +08:00
|
|
|
// init
|
|
|
|
\Typecho\Common::init();
|
|
|
|
} else {
|
2017-10-24 16:59:31 +08:00
|
|
|
require_once dirname(__FILE__) . '/config.inc.php';
|
2021-08-24 01:30:05 +08:00
|
|
|
$installDb = \Typecho\Db::get();
|
2021-08-23 18:43:32 +08:00
|
|
|
}
|
2013-07-17 13:13:57 +08:00
|
|
|
|
2021-08-16 18:34:25 +08:00
|
|
|
/**
|
2021-08-17 01:53:47 +08:00
|
|
|
* get lang
|
2021-08-16 18:34:25 +08:00
|
|
|
*
|
|
|
|
* @return string
|
|
|
|
*/
|
2021-08-23 18:43:32 +08:00
|
|
|
function install_get_lang(): string
|
|
|
|
{
|
|
|
|
$serverLang = \Typecho\Request::getInstance()->getServer('TYPECHO_LANG');
|
2021-08-17 01:53:47 +08:00
|
|
|
|
|
|
|
if (!empty($serverLang)) {
|
|
|
|
return $serverLang;
|
2021-08-16 18:34:25 +08:00
|
|
|
} else {
|
|
|
|
$lang = 'zh_CN';
|
2021-08-23 18:43:32 +08:00
|
|
|
$request = \Typecho\Request::getInstance();
|
2021-08-16 18:34:25 +08:00
|
|
|
|
|
|
|
if ($request->is('lang')) {
|
|
|
|
$lang = $request->get('lang');
|
2021-08-23 18:43:32 +08:00
|
|
|
\Typecho\Cookie::set('lang', $lang);
|
2021-08-16 18:34:25 +08:00
|
|
|
}
|
|
|
|
|
2021-08-23 18:43:32 +08:00
|
|
|
return \Typecho\Cookie::get('lang', $lang);
|
2021-08-16 18:34:25 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2021-08-17 01:53:47 +08:00
|
|
|
* get site url
|
2021-08-16 18:34:25 +08:00
|
|
|
*
|
|
|
|
* @return string
|
|
|
|
*/
|
2021-08-23 18:43:32 +08:00
|
|
|
function install_get_site_url(): string
|
|
|
|
{
|
2021-10-13 14:33:28 +08:00
|
|
|
$request = \Typecho\Request::getInstance();
|
|
|
|
return install_is_cli() ? $request->getServer('TYPECHO_SITE_URL', 'http://localhost') : $request->getRequestRoot();
|
2021-08-16 18:34:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2021-08-17 01:53:47 +08:00
|
|
|
* detect cli mode
|
|
|
|
*
|
|
|
|
* @return bool
|
|
|
|
*/
|
2021-08-23 18:43:32 +08:00
|
|
|
function install_is_cli(): bool
|
|
|
|
{
|
2021-08-26 15:00:38 +08:00
|
|
|
return \Typecho\Request::getInstance()->isCli();
|
2021-08-17 01:53:47 +08:00
|
|
|
}
|
|
|
|
|
2021-08-30 14:52:52 +08:00
|
|
|
/**
|
|
|
|
* get default router
|
|
|
|
*
|
|
|
|
* @return string[][]
|
|
|
|
*/
|
|
|
|
function install_get_default_routers(): array
|
|
|
|
{
|
|
|
|
return [
|
|
|
|
'index' =>
|
|
|
|
[
|
|
|
|
'url' => '/',
|
|
|
|
'widget' => '\Widget\Archive',
|
|
|
|
'action' => 'render',
|
|
|
|
],
|
|
|
|
'archive' =>
|
|
|
|
[
|
|
|
|
'url' => '/blog/',
|
|
|
|
'widget' => '\Widget\Archive',
|
|
|
|
'action' => 'render',
|
|
|
|
],
|
|
|
|
'do' =>
|
|
|
|
[
|
|
|
|
'url' => '/action/[action:alpha]',
|
|
|
|
'widget' => '\Widget\Action',
|
|
|
|
'action' => 'action',
|
|
|
|
],
|
|
|
|
'post' =>
|
|
|
|
[
|
|
|
|
'url' => '/archives/[cid:digital]/',
|
|
|
|
'widget' => '\Widget\Archive',
|
|
|
|
'action' => 'render',
|
|
|
|
],
|
|
|
|
'attachment' =>
|
|
|
|
[
|
|
|
|
'url' => '/attachment/[cid:digital]/',
|
|
|
|
'widget' => '\Widget\Archive',
|
|
|
|
'action' => 'render',
|
|
|
|
],
|
|
|
|
'category' =>
|
|
|
|
[
|
|
|
|
'url' => '/category/[slug]/',
|
|
|
|
'widget' => '\Widget\Archive',
|
|
|
|
'action' => 'render',
|
|
|
|
],
|
|
|
|
'tag' =>
|
|
|
|
[
|
|
|
|
'url' => '/tag/[slug]/',
|
|
|
|
'widget' => '\Widget\Archive',
|
|
|
|
'action' => 'render',
|
|
|
|
],
|
|
|
|
'author' =>
|
|
|
|
[
|
|
|
|
'url' => '/author/[uid:digital]/',
|
|
|
|
'widget' => '\Widget\Archive',
|
|
|
|
'action' => 'render',
|
|
|
|
],
|
|
|
|
'search' =>
|
|
|
|
[
|
|
|
|
'url' => '/search/[keywords]/',
|
|
|
|
'widget' => '\Widget\Archive',
|
|
|
|
'action' => 'render',
|
|
|
|
],
|
|
|
|
'index_page' =>
|
|
|
|
[
|
|
|
|
'url' => '/page/[page:digital]/',
|
|
|
|
'widget' => '\Widget\Archive',
|
|
|
|
'action' => 'render',
|
|
|
|
],
|
|
|
|
'archive_page' =>
|
|
|
|
[
|
|
|
|
'url' => '/blog/page/[page:digital]/',
|
|
|
|
'widget' => '\Widget\Archive',
|
|
|
|
'action' => 'render',
|
|
|
|
],
|
|
|
|
'category_page' =>
|
|
|
|
[
|
|
|
|
'url' => '/category/[slug]/[page:digital]/',
|
|
|
|
'widget' => '\Widget\Archive',
|
|
|
|
'action' => 'render',
|
|
|
|
],
|
|
|
|
'tag_page' =>
|
|
|
|
[
|
|
|
|
'url' => '/tag/[slug]/[page:digital]/',
|
|
|
|
'widget' => '\Widget\Archive',
|
|
|
|
'action' => 'render',
|
|
|
|
],
|
|
|
|
'author_page' =>
|
|
|
|
[
|
|
|
|
'url' => '/author/[uid:digital]/[page:digital]/',
|
|
|
|
'widget' => '\Widget\Archive',
|
|
|
|
'action' => 'render',
|
|
|
|
],
|
|
|
|
'search_page' =>
|
|
|
|
[
|
|
|
|
'url' => '/search/[keywords]/[page:digital]/',
|
|
|
|
'widget' => '\Widget\Archive',
|
|
|
|
'action' => 'render',
|
|
|
|
],
|
|
|
|
'archive_year' =>
|
|
|
|
[
|
|
|
|
'url' => '/[year:digital:4]/',
|
|
|
|
'widget' => '\Widget\Archive',
|
|
|
|
'action' => 'render',
|
|
|
|
],
|
|
|
|
'archive_month' =>
|
|
|
|
[
|
|
|
|
'url' => '/[year:digital:4]/[month:digital:2]/',
|
|
|
|
'widget' => '\Widget\Archive',
|
|
|
|
'action' => 'render',
|
|
|
|
],
|
|
|
|
'archive_day' =>
|
|
|
|
[
|
|
|
|
'url' => '/[year:digital:4]/[month:digital:2]/[day:digital:2]/',
|
|
|
|
'widget' => '\Widget\Archive',
|
|
|
|
'action' => 'render',
|
|
|
|
],
|
|
|
|
'archive_year_page' =>
|
|
|
|
[
|
|
|
|
'url' => '/[year:digital:4]/page/[page:digital]/',
|
|
|
|
'widget' => '\Widget\Archive',
|
|
|
|
'action' => 'render',
|
|
|
|
],
|
|
|
|
'archive_month_page' =>
|
|
|
|
[
|
|
|
|
'url' => '/[year:digital:4]/[month:digital:2]/page/[page:digital]/',
|
|
|
|
'widget' => '\Widget\Archive',
|
|
|
|
'action' => 'render',
|
|
|
|
],
|
|
|
|
'archive_day_page' =>
|
|
|
|
[
|
|
|
|
'url' => '/[year:digital:4]/[month:digital:2]/[day:digital:2]/page/[page:digital]/',
|
|
|
|
'widget' => '\Widget\Archive',
|
|
|
|
'action' => 'render',
|
|
|
|
],
|
|
|
|
'comment_page' =>
|
|
|
|
[
|
|
|
|
'url' => '[permalink:string]/comment-page-[commentPage:digital]',
|
2023-12-30 23:02:25 +08:00
|
|
|
'widget' => '\Widget\CommentPage',
|
|
|
|
'action' => 'action',
|
2021-08-30 14:52:52 +08:00
|
|
|
],
|
|
|
|
'feed' =>
|
|
|
|
[
|
|
|
|
'url' => '/feed[feed:string:0]',
|
2023-12-30 23:02:25 +08:00
|
|
|
'widget' => '\Widget\Feed',
|
|
|
|
'action' => 'render',
|
2021-08-30 14:52:52 +08:00
|
|
|
],
|
|
|
|
'feedback' =>
|
|
|
|
[
|
|
|
|
'url' => '[permalink:string]/[type:alpha]',
|
|
|
|
'widget' => '\Widget\Feedback',
|
|
|
|
'action' => 'action',
|
|
|
|
],
|
|
|
|
'page' =>
|
|
|
|
[
|
|
|
|
'url' => '/[slug].html',
|
|
|
|
'widget' => '\Widget\Archive',
|
|
|
|
'action' => 'render',
|
|
|
|
],
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
2021-08-17 01:53:47 +08:00
|
|
|
/**
|
|
|
|
* list all default options
|
2021-08-16 18:34:25 +08:00
|
|
|
*
|
|
|
|
* @return array
|
|
|
|
*/
|
2021-08-23 18:43:32 +08:00
|
|
|
function install_get_default_options(): array
|
|
|
|
{
|
2021-08-18 16:09:22 +08:00
|
|
|
static $options;
|
|
|
|
|
|
|
|
if (empty($options)) {
|
|
|
|
$options = [
|
|
|
|
'theme' => 'default',
|
2023-12-30 23:02:25 +08:00
|
|
|
'theme:default' => json_encode([
|
|
|
|
'logoUrl' => '',
|
|
|
|
'sidebarBlock' => [
|
|
|
|
'ShowRecentPosts',
|
|
|
|
'ShowRecentComments',
|
|
|
|
'ShowCategory',
|
|
|
|
'ShowArchive',
|
|
|
|
'ShowOther'
|
|
|
|
]
|
|
|
|
]),
|
2021-08-18 16:09:22 +08:00
|
|
|
'timezone' => '28800',
|
|
|
|
'lang' => install_get_lang(),
|
2021-08-26 15:00:38 +08:00
|
|
|
'charset' => 'UTF-8',
|
2021-08-18 16:09:22 +08:00
|
|
|
'contentType' => 'text/html',
|
|
|
|
'gzip' => 0,
|
2021-08-23 18:43:32 +08:00
|
|
|
'generator' => 'Typecho ' . \Typecho\Common::VERSION,
|
2021-08-18 16:09:22 +08:00
|
|
|
'title' => 'Hello World',
|
|
|
|
'description' => 'Your description here.',
|
|
|
|
'keywords' => 'typecho,php,blog',
|
|
|
|
'rewrite' => 0,
|
|
|
|
'frontPage' => 'recent',
|
|
|
|
'frontArchive' => 0,
|
|
|
|
'commentsRequireMail' => 1,
|
|
|
|
'commentsWhitelist' => 0,
|
2023-12-30 23:02:25 +08:00
|
|
|
'commentsRequireUrl' => 0,
|
2021-08-18 16:09:22 +08:00
|
|
|
'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,
|
2023-12-30 23:02:25 +08:00
|
|
|
'routingTable' => json_encode(install_get_default_routers()),
|
|
|
|
'actionTable' => json_encode([]),
|
|
|
|
'panelTable' => json_encode([]),
|
2021-08-18 16:09:22 +08:00
|
|
|
'attachmentTypes' => '@image@',
|
2021-08-23 18:43:32 +08:00
|
|
|
'secret' => \Typecho\Common::randString(32, true),
|
2021-08-18 16:09:22 +08:00
|
|
|
'installed' => 0,
|
|
|
|
'allowXmlRpc' => 2
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
return $options;
|
2021-08-16 18:34:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2021-08-17 01:53:47 +08:00
|
|
|
* get database driver type
|
|
|
|
*
|
|
|
|
* @param string $driver
|
|
|
|
* @return string
|
|
|
|
*/
|
2021-08-23 18:43:32 +08:00
|
|
|
function install_get_db_type(string $driver): string
|
|
|
|
{
|
2021-08-17 01:53:47 +08:00
|
|
|
$parts = explode('_', $driver);
|
|
|
|
return $driver == 'Mysqli' ? 'Mysql' : array_pop($parts);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* list all available database drivers
|
2021-08-16 18:34:25 +08:00
|
|
|
*
|
|
|
|
* @return array
|
|
|
|
*/
|
2021-08-23 18:43:32 +08:00
|
|
|
function install_get_db_drivers(): array
|
|
|
|
{
|
2021-08-16 18:34:25 +08:00
|
|
|
$drivers = [];
|
|
|
|
|
2021-08-23 18:43:32 +08:00
|
|
|
if (\Typecho\Db\Adapter\Pdo\Mysql::isAvailable()) {
|
2021-08-16 18:34:25 +08:00
|
|
|
$drivers['Pdo_Mysql'] = _t('Pdo 驱动 Mysql 适配器');
|
|
|
|
}
|
|
|
|
|
2021-08-23 18:43:32 +08:00
|
|
|
if (\Typecho\Db\Adapter\Pdo\SQLite::isAvailable()) {
|
|
|
|
$drivers['Pdo_SQLite'] = _t('Pdo 驱动 SQLite 适配器');
|
2021-08-16 18:34:25 +08:00
|
|
|
}
|
|
|
|
|
2021-08-23 18:43:32 +08:00
|
|
|
if (\Typecho\Db\Adapter\Pdo\Pgsql::isAvailable()) {
|
2021-08-16 18:34:25 +08:00
|
|
|
$drivers['Pdo_Pgsql'] = _t('Pdo 驱动 PostgreSql 适配器');
|
|
|
|
}
|
|
|
|
|
2021-08-23 18:43:32 +08:00
|
|
|
if (\Typecho\Db\Adapter\Mysqli::isAvailable()) {
|
2021-08-18 00:41:48 +08:00
|
|
|
$drivers['Mysqli'] = _t('Mysql 原生函数适配器');
|
|
|
|
}
|
|
|
|
|
2021-08-23 18:43:32 +08:00
|
|
|
if (\Typecho\Db\Adapter\SQLite::isAvailable()) {
|
|
|
|
$drivers['SQLite'] = _t('SQLite 原生函数适配器');
|
2021-08-18 00:41:48 +08:00
|
|
|
}
|
|
|
|
|
2021-08-23 18:43:32 +08:00
|
|
|
if (\Typecho\Db\Adapter\Pgsql::isAvailable()) {
|
2021-08-18 00:41:48 +08:00
|
|
|
$drivers['Pgsql'] = _t('Pgsql 原生函数适配器');
|
|
|
|
}
|
|
|
|
|
2021-08-16 18:34:25 +08:00
|
|
|
return $drivers;
|
|
|
|
}
|
|
|
|
|
2021-08-17 18:36:54 +08:00
|
|
|
/**
|
|
|
|
* get current db driver
|
|
|
|
*
|
|
|
|
* @return string
|
|
|
|
*/
|
2021-08-23 18:43:32 +08:00
|
|
|
function install_get_current_db_driver(): string
|
|
|
|
{
|
2021-08-17 18:36:54 +08:00
|
|
|
global $installDb;
|
|
|
|
|
|
|
|
if (empty($installDb)) {
|
2021-08-23 18:43:32 +08:00
|
|
|
$driver = \Typecho\Request::getInstance()->get('driver');
|
2021-08-17 18:36:54 +08:00
|
|
|
$drivers = install_get_db_drivers();
|
|
|
|
|
|
|
|
if (empty($driver) || !isset($drivers[$driver])) {
|
|
|
|
return key($drivers);
|
|
|
|
}
|
|
|
|
|
|
|
|
return $driver;
|
|
|
|
} else {
|
|
|
|
return $installDb->getAdapterName();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-08-17 01:53:47 +08:00
|
|
|
/**
|
|
|
|
* generate config file
|
|
|
|
*
|
|
|
|
* @param string $adapter
|
|
|
|
* @param string $dbPrefix
|
|
|
|
* @param array $dbConfig
|
2021-08-18 16:09:22 +08:00
|
|
|
* @param bool $return
|
2021-08-17 01:53:47 +08:00
|
|
|
* @return string
|
|
|
|
*/
|
2021-08-23 18:43:32 +08:00
|
|
|
function install_config_file(string $adapter, string $dbPrefix, array $dbConfig, bool $return = false): string
|
|
|
|
{
|
2021-08-17 18:36:54 +08:00
|
|
|
global $configWritten;
|
|
|
|
|
2021-08-23 18:43:32 +08:00
|
|
|
$code = "<" . "?php
|
|
|
|
// site root path
|
|
|
|
define('__TYPECHO_ROOT_DIR__', dirname(__FILE__));
|
|
|
|
|
|
|
|
// plugin directory (relative path)
|
|
|
|
define('__TYPECHO_PLUGIN_DIR__', '/usr/plugins');
|
|
|
|
|
|
|
|
// theme directory (relative path)
|
|
|
|
define('__TYPECHO_THEME_DIR__', '/usr/themes');
|
|
|
|
|
|
|
|
// admin directory (relative path)
|
|
|
|
define('__TYPECHO_ADMIN_DIR__', '/admin/');
|
|
|
|
|
|
|
|
// register autoload
|
|
|
|
require_once __TYPECHO_ROOT_DIR__ . '/var/Typecho/Common.php';
|
|
|
|
|
|
|
|
// init
|
|
|
|
\Typecho\Common::init();
|
2021-09-05 10:47:29 +08:00
|
|
|
|
2021-08-23 18:43:32 +08:00
|
|
|
// config db
|
2021-08-24 01:30:05 +08:00
|
|
|
\$db = new \Typecho\Db('{$adapter}', '{$dbPrefix}');
|
|
|
|
\$db->addServer(" . (var_export($dbConfig, true)) . ", \Typecho\Db::READ | \Typecho\Db::WRITE);
|
|
|
|
\Typecho\Db::set(\$db);
|
2021-08-17 01:53:47 +08:00
|
|
|
";
|
2021-08-17 18:36:54 +08:00
|
|
|
|
2021-08-18 16:09:22 +08:00
|
|
|
$configWritten = false;
|
|
|
|
|
|
|
|
if (!$return) {
|
|
|
|
$configWritten = @file_put_contents(__TYPECHO_ROOT_DIR__ . '/config.inc.php', $code) !== false;
|
|
|
|
}
|
|
|
|
|
2021-08-17 18:36:54 +08:00
|
|
|
return $code;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* remove config file if written
|
|
|
|
*/
|
2021-08-23 18:43:32 +08:00
|
|
|
function install_remove_config_file()
|
|
|
|
{
|
2021-08-17 18:36:54 +08:00
|
|
|
global $configWritten;
|
|
|
|
|
|
|
|
if ($configWritten) {
|
|
|
|
unlink(__TYPECHO_ROOT_DIR__ . '/config.inc.php');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* check install
|
|
|
|
*
|
|
|
|
* @param string $type
|
|
|
|
* @return bool
|
|
|
|
*/
|
2021-08-23 18:43:32 +08:00
|
|
|
function install_check(string $type): bool
|
|
|
|
{
|
2021-08-17 18:36:54 +08:00
|
|
|
switch ($type) {
|
|
|
|
case 'config':
|
|
|
|
return file_exists(__TYPECHO_ROOT_DIR__ . '/config.inc.php');
|
|
|
|
case 'db_structure':
|
|
|
|
case 'db_data':
|
|
|
|
global $installDb;
|
|
|
|
|
|
|
|
if (empty($installDb)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
|
|
|
// check if table exists
|
2021-09-17 15:06:05 +08:00
|
|
|
$installed = $installDb->fetchRow($installDb->select()->from('table.options')
|
|
|
|
->where('user = 0 AND name = ?', 'installed'));
|
2021-08-17 18:36:54 +08:00
|
|
|
|
2021-09-17 15:06:05 +08:00
|
|
|
if ($type == 'db_data' && empty($installed['value'])) {
|
2021-08-17 18:36:54 +08:00
|
|
|
return false;
|
|
|
|
}
|
2021-09-05 10:47:29 +08:00
|
|
|
} catch (\Typecho\Db\Adapter\ConnectionException $e) {
|
|
|
|
return true;
|
|
|
|
} catch (\Typecho\Db\Adapter\SQLException $e) {
|
2021-08-17 18:36:54 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
2021-08-17 01:53:47 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* raise install error
|
|
|
|
*
|
|
|
|
* @param mixed $error
|
|
|
|
* @param mixed $config
|
|
|
|
*/
|
2021-08-23 18:43:32 +08:00
|
|
|
function install_raise_error($error, $config = null)
|
|
|
|
{
|
2021-08-17 18:36:54 +08:00
|
|
|
if (install_is_cli()) {
|
|
|
|
if (is_array($error)) {
|
|
|
|
foreach ($error as $key => $value) {
|
2021-08-17 18:39:46 +08:00
|
|
|
echo (is_int($key) ? '' : $key . ': ') . $value . "\n";
|
2021-08-17 18:36:54 +08:00
|
|
|
}
|
|
|
|
} else {
|
2021-08-17 22:44:06 +08:00
|
|
|
echo $error . "\n";
|
2021-08-17 01:53:47 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
exit(1);
|
|
|
|
} else {
|
2021-08-26 15:00:38 +08:00
|
|
|
install_throw_json([
|
2021-08-17 01:53:47 +08:00
|
|
|
'success' => 0,
|
2021-08-17 18:36:54 +08:00
|
|
|
'message' => is_string($error) ? nl2br($error) : $error,
|
2021-08-17 01:53:47 +08:00
|
|
|
'config' => $config
|
|
|
|
]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param $step
|
2021-08-17 18:36:54 +08:00
|
|
|
* @param array|null $config
|
2021-08-17 01:53:47 +08:00
|
|
|
*/
|
2021-08-23 18:43:32 +08:00
|
|
|
function install_success($step, ?array $config = null)
|
|
|
|
{
|
2021-10-13 18:34:46 +08:00
|
|
|
global $installDb;
|
|
|
|
|
2021-08-17 01:53:47 +08:00
|
|
|
if (install_is_cli()) {
|
2021-10-13 18:34:46 +08:00
|
|
|
if ($step == 3) {
|
|
|
|
\Typecho\Db::set($installDb);
|
|
|
|
}
|
|
|
|
|
2021-08-17 18:36:54 +08:00
|
|
|
if ($step > 0) {
|
|
|
|
$method = 'install_step_' . $step . '_perform';
|
|
|
|
$method();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!empty($config)) {
|
2021-08-18 00:41:48 +08:00
|
|
|
[$userName, $userPassword] = $config;
|
|
|
|
echo _t('安装成功') . "\n";
|
|
|
|
echo _t('您的用户名是') . " {$userName}\n";
|
|
|
|
echo _t('您的密码是') . " {$userPassword}\n";
|
2021-08-17 18:36:54 +08:00
|
|
|
}
|
2021-08-18 00:41:48 +08:00
|
|
|
|
|
|
|
exit(0);
|
2021-08-17 01:53:47 +08:00
|
|
|
} else {
|
2021-08-26 15:00:38 +08:00
|
|
|
install_throw_json([
|
2021-08-17 18:36:54 +08:00
|
|
|
'success' => 1,
|
|
|
|
'message' => $step,
|
|
|
|
'config' => $config
|
2021-08-17 01:53:47 +08:00
|
|
|
]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-08-26 15:00:38 +08:00
|
|
|
/**
|
|
|
|
* @param $data
|
|
|
|
*/
|
|
|
|
function install_throw_json($data)
|
|
|
|
{
|
|
|
|
\Typecho\Response::getInstance()->setContentType('application/json')
|
|
|
|
->addResponder(function () use ($data) {
|
|
|
|
echo json_encode($data);
|
|
|
|
})
|
|
|
|
->respond();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param string $url
|
|
|
|
*/
|
|
|
|
function install_redirect(string $url)
|
|
|
|
{
|
|
|
|
\Typecho\Response::getInstance()->setStatus(302)
|
|
|
|
->setHeader('Location', $url)
|
|
|
|
->respond();
|
|
|
|
}
|
|
|
|
|
2021-08-18 00:41:48 +08:00
|
|
|
/**
|
2021-08-18 16:09:22 +08:00
|
|
|
* add common js support
|
2021-08-18 00:41:48 +08:00
|
|
|
*/
|
2021-08-23 18:43:32 +08:00
|
|
|
function install_js_support()
|
|
|
|
{
|
2021-08-17 18:36:54 +08:00
|
|
|
?>
|
2021-08-18 00:41:48 +08:00
|
|
|
<div id="success" class="row typecho-page-main hidden">
|
|
|
|
<div class="col-mb-12 col-tb-8 col-tb-offset-2">
|
|
|
|
<div class="typecho-page-title">
|
|
|
|
<h2><?php _e('安装成功'); ?></h2>
|
|
|
|
</div>
|
|
|
|
<div id="typecho-welcome">
|
|
|
|
<p class="keep-word">
|
|
|
|
<?php _e('您选择了使用原有的数据, 您的用户名和密码和原来的一致'); ?>
|
|
|
|
</p>
|
|
|
|
<p class="fresh-word">
|
|
|
|
<?php _e('您的用户名是'); ?>: <strong class="warning" id="success-user"></strong><br>
|
|
|
|
<?php _e('您的密码是'); ?>: <strong class="warning" id="success-password"></strong>
|
|
|
|
</p>
|
|
|
|
<ul>
|
2021-08-18 16:09:22 +08:00
|
|
|
<li><a id="login-url" href=""><?php _e('点击这里访问您的控制面板'); ?></a></li>
|
|
|
|
<li><a id="site-url" href=""><?php _e('点击这里查看您的 Blog'); ?></a></li>
|
2021-08-18 00:41:48 +08:00
|
|
|
</ul>
|
|
|
|
<p><?php _e('希望您能尽情享用 Typecho 带来的乐趣!'); ?></p>
|
|
|
|
</div>
|
|
|
|
</div>
|
2021-08-17 18:36:54 +08:00
|
|
|
</div>
|
|
|
|
<script>
|
2021-08-18 16:09:22 +08:00
|
|
|
let form = $('form'), errorBox = $('<div></div>');
|
2021-08-17 18:36:54 +08:00
|
|
|
|
2021-08-18 16:09:22 +08:00
|
|
|
errorBox.addClass('message error')
|
|
|
|
.prependTo(form);
|
2021-08-17 18:36:54 +08:00
|
|
|
|
|
|
|
function showError(error) {
|
|
|
|
if (typeof error == 'string') {
|
2021-08-18 16:09:22 +08:00
|
|
|
$(window).scrollTop(0);
|
|
|
|
|
|
|
|
errorBox
|
|
|
|
.html(error)
|
|
|
|
.addClass('fade');
|
2021-08-17 18:36:54 +08:00
|
|
|
} else {
|
|
|
|
for (let k in error) {
|
2021-08-18 16:09:22 +08:00
|
|
|
let input = $('#' + k), msg = error[k], p = $('<p></p>');
|
2021-08-16 18:34:25 +08:00
|
|
|
|
2021-08-18 16:09:22 +08:00
|
|
|
p.addClass('message error')
|
|
|
|
.html(msg)
|
|
|
|
.insertAfter(input);
|
2021-08-16 18:34:25 +08:00
|
|
|
|
2021-08-18 16:09:22 +08:00
|
|
|
input.on('input', function () {
|
2021-08-17 18:36:54 +08:00
|
|
|
p.remove();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
2021-08-17 01:53:47 +08:00
|
|
|
|
2021-08-17 18:36:54 +08:00
|
|
|
return errorBox;
|
|
|
|
}
|
2021-08-16 18:34:25 +08:00
|
|
|
|
2021-08-18 16:09:22 +08:00
|
|
|
form.submit(function (e) {
|
2021-08-17 18:36:54 +08:00
|
|
|
e.preventDefault();
|
2021-08-16 18:34:25 +08:00
|
|
|
|
2021-08-18 16:09:22 +08:00
|
|
|
errorBox.removeClass('fade');
|
|
|
|
$('button', form).attr('disabled', 'disabled');
|
|
|
|
$('.typecho-option .error', form).remove();
|
|
|
|
|
|
|
|
$.ajax({
|
|
|
|
url: form.attr('action'),
|
|
|
|
processData: false,
|
|
|
|
contentType: false,
|
|
|
|
type: 'POST',
|
|
|
|
data: new FormData(this),
|
|
|
|
success: function (data) {
|
|
|
|
$('button', form).removeAttr('disabled');
|
|
|
|
|
|
|
|
if (data.success) {
|
|
|
|
if (data.message) {
|
|
|
|
location.href = '?step=' + data.message;
|
|
|
|
} else {
|
|
|
|
let success = $('#success').removeClass('hidden');
|
2021-08-17 18:36:54 +08:00
|
|
|
|
2021-08-18 16:09:22 +08:00
|
|
|
form.addClass('hidden');
|
2021-08-17 18:36:54 +08:00
|
|
|
|
2021-08-18 16:09:22 +08:00
|
|
|
if (data.config) {
|
|
|
|
success.addClass('fresh');
|
2021-08-17 18:36:54 +08:00
|
|
|
|
2021-08-18 16:09:22 +08:00
|
|
|
$('.typecho-page-main:first').addClass('hidden');
|
|
|
|
$('#success-user').html(data.config[0]);
|
|
|
|
$('#success-password').html(data.config[1]);
|
2021-08-18 00:41:48 +08:00
|
|
|
|
2021-08-18 16:09:22 +08:00
|
|
|
$('#login-url').attr('href', data.config[2]);
|
|
|
|
$('#site-url').attr('href', data.config[3]);
|
|
|
|
} else {
|
|
|
|
success.addClass('keep');
|
|
|
|
}
|
2021-08-17 18:36:54 +08:00
|
|
|
}
|
2021-08-18 16:09:22 +08:00
|
|
|
} else {
|
|
|
|
let el = showError(data.message);
|
2021-08-17 18:36:54 +08:00
|
|
|
|
2021-08-18 16:09:22 +08:00
|
|
|
if (typeof configError == 'function' && data.config) {
|
|
|
|
configError(form, data.config, el);
|
|
|
|
}
|
2021-08-17 18:36:54 +08:00
|
|
|
}
|
2021-08-18 16:09:22 +08:00
|
|
|
},
|
|
|
|
error: function (xhr, error) {
|
|
|
|
showError(error)
|
2021-08-17 18:36:54 +08:00
|
|
|
}
|
|
|
|
});
|
2021-08-18 16:09:22 +08:00
|
|
|
});
|
2021-08-17 18:36:54 +08:00
|
|
|
</script>
|
2021-08-23 18:43:32 +08:00
|
|
|
<?php
|
2021-08-16 18:34:25 +08:00
|
|
|
}
|
|
|
|
|
2021-08-26 15:00:38 +08:00
|
|
|
/**
|
|
|
|
* @param string[] $extensions
|
|
|
|
* @return string|null
|
|
|
|
*/
|
|
|
|
function install_check_extension(array $extensions): ?string
|
|
|
|
{
|
|
|
|
foreach ($extensions as $extension) {
|
|
|
|
if (extension_loaded($extension)) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return _n('缺少PHP扩展', '请在服务器上安装以下PHP扩展中的至少一个', count($extensions))
|
|
|
|
. ': ' . implode(', ', $extensions);
|
|
|
|
}
|
|
|
|
|
2021-08-23 18:43:32 +08:00
|
|
|
function install_step_1()
|
|
|
|
{
|
2021-09-01 17:21:58 +08:00
|
|
|
$langs = \Widget\Options\General::getLangs();
|
2021-08-16 18:34:25 +08:00
|
|
|
$lang = install_get_lang();
|
2021-08-23 18:43:32 +08:00
|
|
|
?>
|
2021-08-17 18:36:54 +08:00
|
|
|
<div class="row typecho-page-main">
|
|
|
|
<div class="col-mb-12 col-tb-8 col-tb-offset-2">
|
|
|
|
<div class="typecho-page-title">
|
|
|
|
<h2><?php _e('欢迎使用 Typecho'); ?></h2>
|
|
|
|
</div>
|
|
|
|
<div id="typecho-welcome">
|
2021-08-26 15:00:38 +08:00
|
|
|
<form autocomplete="off" method="post" action="install.php">
|
2021-08-17 18:36:54 +08:00
|
|
|
<h3><?php _e('安装说明'); ?></h3>
|
2021-08-18 16:09:22 +08:00
|
|
|
<p class="warning">
|
|
|
|
<strong><?php _e('本安装程序将自动检测服务器环境是否符合最低配置需求. 如果不符合, 将在上方出现提示信息, 请按照提示信息检查您的主机配置. 如果服务器环境符合要求, 将在下方出现 "开始下一步" 的按钮, 点击此按钮即可一步完成安装.'); ?></strong>
|
|
|
|
</p>
|
2021-08-17 18:36:54 +08:00
|
|
|
<h3><?php _e('许可及协议'); ?></h3>
|
|
|
|
<ul>
|
2023-03-28 11:57:45 +08:00
|
|
|
<li><?php _e('Typecho 基于 <a href="https://www.gnu.org/copyleft/gpl.html">GPL</a> 协议发布, 我们允许用户在 GPL 协议许可的范围内使用, 拷贝, 修改和分发此程序.'); ?>
|
2021-08-17 18:36:54 +08:00
|
|
|
<?php _e('在GPL许可的范围内, 您可以自由地将其用于商业以及非商业用途.'); ?></li>
|
|
|
|
<li><?php _e('Typecho 软件由其社区提供支持, 核心开发团队负责维护程序日常开发工作以及新特性的制定.'); ?>
|
|
|
|
<?php _e('如果您遇到使用上的问题, 程序中的 BUG, 以及期许的新功能, 欢迎您在社区中交流或者直接向我们贡献代码.'); ?>
|
|
|
|
<?php _e('对于贡献突出者, 他的名字将出现在贡献者名单中.'); ?></li>
|
|
|
|
</ul>
|
|
|
|
|
|
|
|
<p class="submit">
|
|
|
|
<button class="btn primary" type="submit"><?php _e('我准备好了, 开始下一步 »'); ?></button>
|
2021-08-26 15:00:38 +08:00
|
|
|
<input type="hidden" name="step" value="1">
|
2021-08-17 18:36:54 +08:00
|
|
|
|
2021-08-23 18:43:32 +08:00
|
|
|
<?php if (count($langs) > 1) : ?>
|
2021-08-17 18:36:54 +08:00
|
|
|
<select style="float: right" onchange="location.href='?lang=' + this.value">
|
2021-08-23 18:43:32 +08:00
|
|
|
<?php foreach ($langs as $key => $val) : ?>
|
|
|
|
<option value="<?php echo $key; ?>"<?php if ($lang == $key) :
|
|
|
|
?> selected<?php
|
|
|
|
endif; ?>><?php echo $val; ?></option>
|
2021-08-17 18:36:54 +08:00
|
|
|
<?php endforeach; ?>
|
|
|
|
</select>
|
|
|
|
<?php endif; ?>
|
|
|
|
</p>
|
|
|
|
</form>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
2021-08-23 18:43:32 +08:00
|
|
|
<?php
|
2021-08-26 15:00:38 +08:00
|
|
|
install_js_support();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* check dependencies before install
|
|
|
|
*/
|
|
|
|
function install_step_1_perform()
|
|
|
|
{
|
|
|
|
$errors = [];
|
|
|
|
$checks = [
|
|
|
|
'mbstring',
|
|
|
|
'json',
|
2021-08-31 00:18:56 +08:00
|
|
|
'Reflection',
|
2021-08-26 15:00:38 +08:00
|
|
|
['mysqli', 'sqlite3', 'pgsql', 'pdo_mysql', 'pdo_sqlite', 'pdo_pgsql']
|
|
|
|
];
|
|
|
|
|
|
|
|
foreach ($checks as $check) {
|
|
|
|
$error = install_check_extension(is_array($check) ? $check : [$check]);
|
|
|
|
|
|
|
|
if (!empty($error)) {
|
|
|
|
$errors[] = $error;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$uploadDir = '/usr/uploads';
|
|
|
|
$realUploadDir = \Typecho\Common::url($uploadDir, __TYPECHO_ROOT_DIR__);
|
|
|
|
$writeable = true;
|
|
|
|
if (is_dir($realUploadDir)) {
|
2023-12-30 23:02:25 +08:00
|
|
|
if (!is_writable($realUploadDir) || !is_readable($realUploadDir)) {
|
2021-09-15 14:59:08 +08:00
|
|
|
if (!@chmod($realUploadDir, 0755)) {
|
2021-08-26 15:00:38 +08:00
|
|
|
$writeable = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2021-09-15 14:59:08 +08:00
|
|
|
if (!@mkdir($realUploadDir, 0755)) {
|
2021-08-26 15:00:38 +08:00
|
|
|
$writeable = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!$writeable) {
|
|
|
|
$errors[] = _t('上传目录无法写入, 请手动将安装目录下的 %s 目录的权限设置为可写然后继续升级', $uploadDir);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (empty($errors)) {
|
|
|
|
install_success(2);
|
|
|
|
} else {
|
|
|
|
install_raise_error(implode("\n", $errors));
|
|
|
|
}
|
2021-08-16 18:34:25 +08:00
|
|
|
}
|
|
|
|
|
2021-08-17 01:53:47 +08:00
|
|
|
/**
|
|
|
|
* display step 2
|
|
|
|
*/
|
2021-08-23 18:43:32 +08:00
|
|
|
function install_step_2()
|
|
|
|
{
|
2021-08-17 18:36:54 +08:00
|
|
|
global $installDb;
|
|
|
|
|
2021-08-16 18:34:25 +08:00
|
|
|
$drivers = install_get_db_drivers();
|
2021-08-17 18:36:54 +08:00
|
|
|
$adapter = install_get_current_db_driver();
|
2021-08-17 01:53:47 +08:00
|
|
|
$type = install_get_db_type($adapter);
|
|
|
|
|
2021-08-17 18:36:54 +08:00
|
|
|
if (!empty($installDb)) {
|
2021-08-24 01:30:05 +08:00
|
|
|
$config = $installDb->getConfig(\Typecho\Db::WRITE)->toArray();
|
2021-08-17 18:36:54 +08:00
|
|
|
$config['prefix'] = $installDb->getPrefix();
|
|
|
|
$config['adapter'] = $adapter;
|
2021-08-17 01:53:47 +08:00
|
|
|
}
|
2021-08-23 18:43:32 +08:00
|
|
|
?>
|
2021-08-17 18:36:54 +08:00
|
|
|
<div class="row typecho-page-main">
|
|
|
|
<div class="col-mb-12 col-tb-8 col-tb-offset-2">
|
|
|
|
<div class="typecho-page-title">
|
|
|
|
<h2><?php _e('初始化配置'); ?></h2>
|
|
|
|
</div>
|
2021-08-18 16:09:22 +08:00
|
|
|
<form autocomplete="off" action="install.php" method="post">
|
2021-08-17 18:36:54 +08:00
|
|
|
<ul class="typecho-option">
|
|
|
|
<li>
|
|
|
|
<label for="dbAdapter" class="typecho-label"><?php _e('数据库适配器'); ?></label>
|
|
|
|
<select name="dbAdapter" id="dbAdapter" onchange="location.href='?step=2&driver=' + this.value">
|
2021-08-23 18:43:32 +08:00
|
|
|
<?php foreach ($drivers as $driver => $name) : ?>
|
|
|
|
<option value="<?php echo $driver; ?>"<?php if ($driver == $adapter) :
|
|
|
|
?> selected="selected"<?php
|
|
|
|
endif; ?>><?php echo $name; ?></option>
|
2021-08-17 18:36:54 +08:00
|
|
|
<?php endforeach; ?>
|
|
|
|
</select>
|
|
|
|
<p class="description"><?php _e('请根据您的数据库类型选择合适的适配器'); ?></p>
|
|
|
|
<input type="hidden" id="dbNext" name="dbNext" value="none">
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
|
|
<ul class="typecho-option">
|
|
|
|
<li>
|
|
|
|
<label class="typecho-label" for="dbPrefix"><?php _e('数据库前缀'); ?></label>
|
2021-08-20 11:15:11 +08:00
|
|
|
<input type="text" class="text" name="dbPrefix" id="dbPrefix" value="typecho_" />
|
2021-08-17 18:36:54 +08:00
|
|
|
<p class="description"><?php _e('默认前缀是 "typecho_"'); ?></p>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
|
|
<?php require_once './install/' . $type . '.php'; ?>
|
|
|
|
|
|
|
|
|
|
|
|
<ul class="typecho-option typecho-option-submit">
|
|
|
|
<li>
|
2021-08-18 16:09:22 +08:00
|
|
|
<button id="confirm" type="submit" class="btn primary"><?php _e('确认, 开始安装 »'); ?></button>
|
2021-08-17 18:36:54 +08:00
|
|
|
<input type="hidden" name="step" value="2">
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
|
|
</form>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<script>
|
2021-08-18 16:09:22 +08:00
|
|
|
function configError(form, config, errorBox) {
|
|
|
|
let next = $('#dbNext'),
|
|
|
|
line = $('<p></p>');
|
2021-08-17 18:36:54 +08:00
|
|
|
|
|
|
|
if (config.code) {
|
2021-08-18 16:09:22 +08:00
|
|
|
let text = $('<textarea></textarea>'),
|
|
|
|
btn = $('<button></button>');
|
2021-08-17 18:36:54 +08:00
|
|
|
|
2021-08-18 16:09:22 +08:00
|
|
|
btn.html('<?php _e('创建完毕, 继续安装 »'); ?>')
|
|
|
|
.attr('type', 'button')
|
|
|
|
.addClass('btn btn-s primary');
|
|
|
|
|
|
|
|
btn.click(function () {
|
|
|
|
next.val('config');
|
|
|
|
form.trigger('submit');
|
|
|
|
});
|
|
|
|
|
|
|
|
text.val(config.code)
|
|
|
|
.addClass('mono')
|
|
|
|
.attr('readonly', 'readonly');
|
|
|
|
|
|
|
|
errorBox.append(text)
|
|
|
|
.append(btn);
|
2021-08-17 18:36:54 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-08-18 16:09:22 +08:00
|
|
|
errorBox.append(line);
|
2021-08-17 18:36:54 +08:00
|
|
|
|
|
|
|
for (let key in config) {
|
|
|
|
let word = config[key],
|
2021-08-18 16:09:22 +08:00
|
|
|
btn = $('<button></button>');
|
|
|
|
|
|
|
|
btn.html(word)
|
|
|
|
.attr('type', 'button')
|
|
|
|
.addClass('btn btn-s primary')
|
|
|
|
.click(function () {
|
|
|
|
next.val(key);
|
|
|
|
form.trigger('submit');
|
|
|
|
});
|
2021-08-17 18:36:54 +08:00
|
|
|
|
2021-08-18 16:09:22 +08:00
|
|
|
line.append(btn);
|
2021-08-17 18:36:54 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-08-18 16:09:22 +08:00
|
|
|
$('#confirm').click(function () {
|
|
|
|
$('#dbNext').val('none');
|
|
|
|
});
|
|
|
|
|
2021-08-23 18:43:32 +08:00
|
|
|
<?php if (!empty($config)) : ?>
|
2021-08-17 18:36:54 +08:00
|
|
|
function fillInput(config) {
|
|
|
|
for (let k in config) {
|
|
|
|
let value = config[k],
|
|
|
|
key = 'db' + k.charAt(0).toUpperCase() + k.slice(1),
|
2021-08-18 16:09:22 +08:00
|
|
|
input = $('#' + key)
|
|
|
|
.attr('readonly', 'readonly')
|
|
|
|
.val(value);
|
2021-08-17 18:36:54 +08:00
|
|
|
|
2021-08-18 16:09:22 +08:00
|
|
|
$('option:not(:selected)', input).attr('disabled', 'disabled');
|
2021-08-17 18:36:54 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-08-26 15:00:38 +08:00
|
|
|
fillInput(<?php echo json_encode($config); ?>);
|
2021-08-17 18:36:54 +08:00
|
|
|
<?php endif; ?>
|
|
|
|
</script>
|
2021-08-23 18:43:32 +08:00
|
|
|
<?php
|
2021-08-18 16:09:22 +08:00
|
|
|
install_js_support();
|
2021-08-16 18:34:25 +08:00
|
|
|
}
|
|
|
|
|
2021-08-17 18:36:54 +08:00
|
|
|
/**
|
|
|
|
* perform install step 2
|
|
|
|
*/
|
2021-08-23 18:43:32 +08:00
|
|
|
function install_step_2_perform()
|
|
|
|
{
|
2021-08-17 18:36:54 +08:00
|
|
|
global $installDb;
|
|
|
|
|
2021-08-23 18:43:32 +08:00
|
|
|
$request = \Typecho\Request::getInstance();
|
2021-08-17 01:53:47 +08:00
|
|
|
$drivers = install_get_db_drivers();
|
|
|
|
|
|
|
|
$configMap = [
|
|
|
|
'Mysql' => [
|
|
|
|
'dbHost' => 'localhost',
|
|
|
|
'dbPort' => 3306,
|
|
|
|
'dbUser' => null,
|
|
|
|
'dbPassword' => null,
|
|
|
|
'dbCharset' => 'utf8mb4',
|
|
|
|
'dbDatabase' => null,
|
2023-03-29 14:33:23 +08:00
|
|
|
'dbEngine' => 'InnoDB',
|
|
|
|
'dbSslCa' => null,
|
2023-12-30 23:02:25 +08:00
|
|
|
'dbSslVerify' => 'off',
|
2021-08-17 01:53:47 +08:00
|
|
|
],
|
|
|
|
'Pgsql' => [
|
|
|
|
'dbHost' => 'localhost',
|
|
|
|
'dbPort' => 5432,
|
|
|
|
'dbUser' => null,
|
|
|
|
'dbPassword' => null,
|
|
|
|
'dbCharset' => 'utf8',
|
|
|
|
'dbDatabase' => null,
|
2023-12-30 23:02:25 +08:00
|
|
|
'dbSslVerify' => 'off',
|
2021-08-17 01:53:47 +08:00
|
|
|
],
|
|
|
|
'SQLite' => [
|
|
|
|
'dbFile' => __TYPECHO_ROOT_DIR__ . '/usr/' . uniqid() . '.db'
|
|
|
|
]
|
|
|
|
];
|
|
|
|
|
|
|
|
if (install_is_cli()) {
|
|
|
|
$config = [
|
|
|
|
'dbHost' => $request->getServer('TYPECHO_DB_HOST'),
|
|
|
|
'dbUser' => $request->getServer('TYPECHO_DB_USER'),
|
|
|
|
'dbPassword' => $request->getServer('TYPECHO_DB_PASSWORD'),
|
|
|
|
'dbCharset' => $request->getServer('TYPECHO_DB_CHARSET'),
|
|
|
|
'dbPort' => $request->getServer('TYPECHO_DB_PORT'),
|
|
|
|
'dbDatabase' => $request->getServer('TYPECHO_DB_DATABASE'),
|
|
|
|
'dbFile' => $request->getServer('TYPECHO_DB_FILE'),
|
|
|
|
'dbDsn' => $request->getServer('TYPECHO_DB_DSN'),
|
|
|
|
'dbEngine' => $request->getServer('TYPECHO_DB_ENGINE'),
|
2021-08-17 22:44:06 +08:00
|
|
|
'dbPrefix' => $request->getServer('TYPECHO_DB_PREFIX', 'typecho_'),
|
|
|
|
'dbAdapter' => $request->getServer('TYPECHO_DB_ADAPTER', install_get_current_db_driver()),
|
2023-03-29 14:33:23 +08:00
|
|
|
'dbNext' => $request->getServer('TYPECHO_DB_NEXT', 'none'),
|
|
|
|
'dbSslCa' => $request->getServer('TYPECHO_DB_SSL_CA'),
|
2023-12-30 23:02:25 +08:00
|
|
|
'dbSslVerify' => $request->getServer('TYPECHO_DB_SSL_VERIFY', 'off'),
|
2021-08-17 01:53:47 +08:00
|
|
|
];
|
|
|
|
} else {
|
|
|
|
$config = $request->from([
|
|
|
|
'dbHost',
|
|
|
|
'dbUser',
|
|
|
|
'dbPassword',
|
|
|
|
'dbCharset',
|
|
|
|
'dbPort',
|
|
|
|
'dbDatabase',
|
|
|
|
'dbFile',
|
|
|
|
'dbDsn',
|
|
|
|
'dbEngine',
|
|
|
|
'dbPrefix',
|
|
|
|
'dbAdapter',
|
2023-03-29 14:33:23 +08:00
|
|
|
'dbNext',
|
|
|
|
'dbSslCa',
|
|
|
|
'dbSslVerify',
|
2021-08-17 01:53:47 +08:00
|
|
|
]);
|
|
|
|
}
|
|
|
|
|
2021-08-23 18:43:32 +08:00
|
|
|
$error = (new \Typecho\Validate())
|
2021-08-17 01:53:47 +08:00
|
|
|
->addRule('dbPrefix', 'required', _t('确认您的配置'))
|
|
|
|
->addRule('dbPrefix', 'minLength', _t('确认您的配置'), 1)
|
|
|
|
->addRule('dbPrefix', 'maxLength', _t('确认您的配置'), 16)
|
|
|
|
->addRule('dbPrefix', 'alphaDash', _t('确认您的配置'))
|
|
|
|
->addRule('dbAdapter', 'required', _t('确认您的配置'))
|
|
|
|
->addRule('dbAdapter', 'enum', _t('确认您的配置'), array_keys($drivers))
|
|
|
|
->addRule('dbNext', 'required', _t('确认您的配置'))
|
2021-08-18 16:09:22 +08:00
|
|
|
->addRule('dbNext', 'enum', _t('确认您的配置'), ['none', 'delete', 'keep', 'config'])
|
2021-08-17 01:53:47 +08:00
|
|
|
->run($config);
|
|
|
|
|
|
|
|
if (!empty($error)) {
|
|
|
|
install_raise_error($error);
|
|
|
|
}
|
|
|
|
|
|
|
|
$type = install_get_db_type($config['dbAdapter']);
|
|
|
|
$dbConfig = [];
|
|
|
|
|
|
|
|
foreach ($configMap[$type] as $key => $value) {
|
2021-08-24 01:30:05 +08:00
|
|
|
$config[$key] = !isset($config[$key]) ? (install_is_cli() ? $value : null) : $config[$key];
|
2021-08-17 01:53:47 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
switch ($type) {
|
|
|
|
case 'Mysql':
|
2021-08-23 18:43:32 +08:00
|
|
|
$error = (new \Typecho\Validate())
|
2021-08-17 18:36:54 +08:00
|
|
|
->addRule('dbHost', 'required', _t('确认您的配置'))
|
|
|
|
->addRule('dbPort', 'required', _t('确认您的配置'))
|
|
|
|
->addRule('dbPort', 'isInteger', _t('确认您的配置'))
|
|
|
|
->addRule('dbUser', 'required', _t('确认您的配置'))
|
|
|
|
->addRule('dbCharset', 'required', _t('确认您的配置'))
|
|
|
|
->addRule('dbCharset', 'enum', _t('确认您的配置'), ['utf8', 'utf8mb4'])
|
|
|
|
->addRule('dbDatabase', 'required', _t('确认您的配置'))
|
|
|
|
->addRule('dbEngine', 'required', _t('确认您的配置'))
|
|
|
|
->addRule('dbEngine', 'enum', _t('确认您的配置'), ['InnoDB', 'MyISAM'])
|
2023-03-29 14:33:23 +08:00
|
|
|
->addRule('dbSslCa', 'file_exists', _t('确认您的配置'))
|
|
|
|
->addRule('dbSslVerify', 'enum', _t('确认您的配置'), ['on', 'off'])
|
2021-08-18 00:41:48 +08:00
|
|
|
->run($config);
|
2021-08-17 01:53:47 +08:00
|
|
|
break;
|
|
|
|
case 'Pgsql':
|
2021-08-23 18:43:32 +08:00
|
|
|
$error = (new \Typecho\Validate())
|
2021-08-17 18:36:54 +08:00
|
|
|
->addRule('dbHost', 'required', _t('确认您的配置'))
|
|
|
|
->addRule('dbPort', 'required', _t('确认您的配置'))
|
|
|
|
->addRule('dbPort', 'isInteger', _t('确认您的配置'))
|
|
|
|
->addRule('dbUser', 'required', _t('确认您的配置'))
|
|
|
|
->addRule('dbCharset', 'required', _t('确认您的配置'))
|
|
|
|
->addRule('dbCharset', 'enum', _t('确认您的配置'), ['utf8'])
|
|
|
|
->addRule('dbDatabase', 'required', _t('确认您的配置'))
|
2023-12-30 23:02:25 +08:00
|
|
|
->addRule('dbSslVerify', 'enum', _t('确认您的配置'), ['on', 'off'])
|
2021-08-18 00:41:48 +08:00
|
|
|
->run($config);
|
2021-08-17 01:53:47 +08:00
|
|
|
break;
|
|
|
|
case 'SQLite':
|
2021-08-23 18:43:32 +08:00
|
|
|
$error = (new \Typecho\Validate())
|
2021-08-17 18:36:54 +08:00
|
|
|
->addRule('dbFile', 'required', _t('确认您的配置'))
|
2022-03-22 14:24:14 +08:00
|
|
|
->addRule('dbFile', function (string $path) {
|
2022-07-20 00:20:25 +08:00
|
|
|
$pattern = "/^(\/[._a-z0-9-]+)*[a-z0-9]+\.[a-z0-9]{2,}$/i";
|
2023-05-16 12:33:49 +08:00
|
|
|
if (strstr(PHP_OS, 'WIN')) {
|
2022-07-20 00:20:25 +08:00
|
|
|
$pattern = "/(\/[._a-z0-9-]+)*[a-z0-9]+\.[a-z0-9]{2,}$/i";
|
|
|
|
}
|
|
|
|
return !!preg_match($pattern, $path);
|
2022-03-22 14:24:14 +08:00
|
|
|
}, _t('确认您的配置'))
|
2021-08-18 00:41:48 +08:00
|
|
|
->run($config);
|
2021-08-17 01:53:47 +08:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
install_raise_error(_t('确认您的配置'));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!empty($error)) {
|
|
|
|
install_raise_error($error);
|
|
|
|
}
|
|
|
|
|
2021-08-18 00:41:48 +08:00
|
|
|
foreach ($configMap[$type] as $key => $value) {
|
2023-03-29 14:33:23 +08:00
|
|
|
$dbConfig[lcfirst(substr($key, 2))] = $config[$key];
|
2021-08-17 01:53:47 +08:00
|
|
|
}
|
|
|
|
|
2021-09-16 15:42:17 +08:00
|
|
|
// intval port number
|
|
|
|
if (isset($dbConfig['port'])) {
|
|
|
|
$dbConfig['port'] = intval($dbConfig['port']);
|
|
|
|
}
|
|
|
|
|
2023-03-29 14:33:23 +08:00
|
|
|
// bool ssl verify
|
|
|
|
if (isset($dbConfig['sslVerify'])) {
|
2023-12-30 23:02:25 +08:00
|
|
|
$dbConfig['sslVerify'] = $dbConfig['sslVerify'] == 'on' || !empty($dbConfig['sslCa']);
|
2023-03-29 14:33:23 +08:00
|
|
|
}
|
|
|
|
|
2022-03-22 14:24:14 +08:00
|
|
|
if (isset($dbConfig['file']) && preg_match("/^[a-z0-9]+\.[a-z0-9]{2,}$/i", $dbConfig['file'])) {
|
|
|
|
$dbConfig['file'] = __DIR__ . '/usr/' . $dbConfig['file'];
|
|
|
|
}
|
|
|
|
|
2021-08-18 16:09:22 +08:00
|
|
|
// 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)) {
|
2021-08-17 18:36:54 +08:00
|
|
|
// detect db config
|
|
|
|
try {
|
2021-08-24 01:30:05 +08:00
|
|
|
$installDb = new \Typecho\Db($config['dbAdapter'], $config['dbPrefix']);
|
|
|
|
$installDb->addServer($dbConfig, \Typecho\Db::READ | \Typecho\Db::WRITE);
|
2021-08-17 18:36:54 +08:00
|
|
|
$installDb->query('SELECT 1=1');
|
2022-03-15 16:09:32 +08:00
|
|
|
} catch (\Typecho\Db\Adapter\ConnectionException $e) {
|
2023-05-16 14:33:26 +08:00
|
|
|
$code = $e->getCode();
|
|
|
|
if (('Mysql' == $type && 1049 == $code) || ('Pgsql' == $type && 7 == $code)) {
|
|
|
|
install_raise_error(_t('数据库: "%s"不存在,请手动创建后重试', $config['dbDatabase']));
|
|
|
|
} else {
|
|
|
|
install_raise_error(_t('对不起, 无法连接数据库, 请先检查数据库配置再继续进行安装: "%s"', $e->getMessage()));
|
|
|
|
}
|
2021-08-23 18:43:32 +08:00
|
|
|
} catch (\Typecho\Db\Exception $e) {
|
2022-03-24 17:46:03 +08:00
|
|
|
install_raise_error(_t('安装程序捕捉到以下错误: "%s". 程序被终止, 请检查您的配置信息.', $e->getMessage()));
|
2021-08-17 18:36:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
$code = install_config_file($config['dbAdapter'], $config['dbPrefix'], $dbConfig);
|
|
|
|
|
|
|
|
if (!install_check('config')) {
|
|
|
|
install_raise_error(
|
|
|
|
_t('安装程序无法自动创建 <strong>config.inc.php</strong> 文件') . "\n" .
|
2021-08-23 18:43:32 +08:00
|
|
|
_t('您可以在网站根目录下手动创建 <strong>config.inc.php</strong> 文件, 并复制如下代码至其中'),
|
|
|
|
[
|
2021-08-17 18:36:54 +08:00
|
|
|
'code' => $code
|
2021-08-23 18:43:32 +08:00
|
|
|
]
|
|
|
|
);
|
2021-08-17 18:36:54 +08:00
|
|
|
}
|
2021-08-17 01:53:47 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// delete exists db
|
2021-08-23 18:43:32 +08:00
|
|
|
if ($config['dbNext'] == 'delete') {
|
2021-08-17 01:53:47 +08:00
|
|
|
$tables = [
|
|
|
|
$config['dbPrefix'] . 'comments',
|
|
|
|
$config['dbPrefix'] . 'contents',
|
|
|
|
$config['dbPrefix'] . 'fields',
|
|
|
|
$config['dbPrefix'] . 'metas',
|
|
|
|
$config['dbPrefix'] . 'options',
|
|
|
|
$config['dbPrefix'] . 'relationships',
|
|
|
|
$config['dbPrefix'] . 'users'
|
|
|
|
];
|
|
|
|
|
|
|
|
try {
|
|
|
|
foreach ($tables as $table) {
|
2022-03-24 17:46:03 +08:00
|
|
|
switch ($type) {
|
|
|
|
case 'Mysql':
|
|
|
|
$installDb->query("DROP TABLE IF EXISTS `{$table}`");
|
|
|
|
break;
|
|
|
|
case 'Pgsql':
|
|
|
|
case 'SQLite':
|
|
|
|
$installDb->query("DROP TABLE {$table}");
|
|
|
|
break;
|
2021-08-17 01:53:47 +08:00
|
|
|
}
|
|
|
|
}
|
2021-08-23 18:43:32 +08:00
|
|
|
} catch (\Typecho\Db\Exception $e) {
|
2021-08-17 01:53:47 +08:00
|
|
|
install_raise_error(_t('安装程序捕捉到以下错误: "%s". 程序被终止, 请检查您的配置信息.', $e->getMessage()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// init db structure
|
|
|
|
try {
|
|
|
|
$scripts = file_get_contents(__TYPECHO_ROOT_DIR__ . '/install/' . $type . '.sql');
|
|
|
|
$scripts = str_replace('typecho_', $config['dbPrefix'], $scripts);
|
|
|
|
|
|
|
|
if (isset($dbConfig['charset'])) {
|
|
|
|
$scripts = str_replace('%charset%', $dbConfig['charset'], $scripts);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isset($dbConfig['engine'])) {
|
|
|
|
$scripts = str_replace('%engine%', $dbConfig['engine'], $scripts);
|
|
|
|
}
|
|
|
|
|
|
|
|
$scripts = explode(';', $scripts);
|
|
|
|
foreach ($scripts as $script) {
|
|
|
|
$script = trim($script);
|
|
|
|
if ($script) {
|
2021-08-24 01:30:05 +08:00
|
|
|
$installDb->query($script, \Typecho\Db::WRITE);
|
2021-08-17 01:53:47 +08:00
|
|
|
}
|
|
|
|
}
|
2021-08-23 18:43:32 +08:00
|
|
|
} catch (\Typecho\Db\Exception $e) {
|
2021-08-17 01:53:47 +08:00
|
|
|
$code = $e->getCode();
|
|
|
|
|
2021-08-23 18:43:32 +08:00
|
|
|
if (
|
|
|
|
('Mysql' == $type && (1050 == $code || '42S01' == $code)) ||
|
2021-08-17 01:53:47 +08:00
|
|
|
('SQLite' == $type && ('HY000' == $code || 1 == $code)) ||
|
2021-08-23 18:43:32 +08:00
|
|
|
('Pgsql' == $type && '42P07' == $code)
|
|
|
|
) {
|
2021-08-17 01:53:47 +08:00
|
|
|
if ($config['dbNext'] == 'keep') {
|
2021-08-17 18:36:54 +08:00
|
|
|
if (install_check('db_data')) {
|
|
|
|
install_success(0);
|
|
|
|
} else {
|
|
|
|
install_success(3);
|
|
|
|
}
|
|
|
|
} elseif ($config['dbNext'] == 'none') {
|
|
|
|
install_remove_config_file();
|
|
|
|
|
2021-08-17 01:53:47 +08:00
|
|
|
install_raise_error(_t('安装程序检查到原有数据表已经存在.'), [
|
|
|
|
'delete' => _t('删除原有数据'),
|
|
|
|
'keep' => _t('使用原有数据')
|
|
|
|
]);
|
|
|
|
}
|
|
|
|
} else {
|
2021-08-17 18:36:54 +08:00
|
|
|
install_remove_config_file();
|
|
|
|
|
2021-08-17 01:53:47 +08:00
|
|
|
install_raise_error(_t('安装程序捕捉到以下错误: "%s". 程序被终止, 请检查您的配置信息.', $e->getMessage()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
install_success(3);
|
|
|
|
}
|
|
|
|
|
2021-08-17 18:36:54 +08:00
|
|
|
/**
|
|
|
|
* display step 3
|
|
|
|
*/
|
2021-08-23 18:43:32 +08:00
|
|
|
function install_step_3()
|
|
|
|
{
|
2021-08-30 14:52:52 +08:00
|
|
|
$options = \Widget\Options::alloc();
|
2021-08-23 18:43:32 +08:00
|
|
|
?>
|
2021-08-17 18:36:54 +08:00
|
|
|
<div class="row typecho-page-main">
|
|
|
|
<div class="col-mb-12 col-tb-8 col-tb-offset-2">
|
|
|
|
<div class="typecho-page-title">
|
|
|
|
<h2><?php _e('创建您的管理员帐号'); ?></h2>
|
|
|
|
</div>
|
2021-08-18 16:09:22 +08:00
|
|
|
<form autocomplete="off" action="install.php" method="post">
|
2021-08-17 18:36:54 +08:00
|
|
|
<ul class="typecho-option">
|
|
|
|
<li>
|
|
|
|
<label class="typecho-label" for="userUrl"><?php _e('网站地址'); ?></label>
|
2021-09-15 14:33:23 +08:00
|
|
|
<input autocomplete="new-password" type="text" name="userUrl" id="userUrl" class="text" value="<?php $options->rootUrl(); ?>" />
|
2021-08-17 18:36:54 +08:00
|
|
|
<p class="description"><?php _e('这是程序自动匹配的网站路径, 如果不正确请修改它'); ?></p>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
|
|
<ul class="typecho-option">
|
|
|
|
<li>
|
|
|
|
<label class="typecho-label" for="userName"><?php _e('用户名'); ?></label>
|
2021-08-18 16:09:22 +08:00
|
|
|
<input autocomplete="new-password" type="text" name="userName" id="userName" class="text" />
|
2021-08-17 18:36:54 +08:00
|
|
|
<p class="description"><?php _e('请填写您的用户名'); ?></p>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
|
|
<ul class="typecho-option">
|
|
|
|
<li>
|
|
|
|
<label class="typecho-label" for="userPassword"><?php _e('登录密码'); ?></label>
|
|
|
|
<input type="password" name="userPassword" id="userPassword" class="text" />
|
|
|
|
<p class="description"><?php _e('请填写您的登录密码, 如果留空系统将为您随机生成一个'); ?></p>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
|
|
<ul class="typecho-option">
|
|
|
|
<li>
|
|
|
|
<label class="typecho-label" for="userMail"><?php _e('邮件地址'); ?></label>
|
2021-08-18 16:09:22 +08:00
|
|
|
<input autocomplete="new-password" type="text" name="userMail" id="userMail" class="text" />
|
2021-08-17 18:36:54 +08:00
|
|
|
<p class="description"><?php _e('请填写一个您的常用邮箱'); ?></p>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
|
|
<ul class="typecho-option typecho-option-submit">
|
|
|
|
<li>
|
|
|
|
<button type="submit" class="btn primary"><?php _e('继续安装 »'); ?></button>
|
|
|
|
<input type="hidden" name="step" value="3">
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
|
|
</form>
|
|
|
|
</div>
|
|
|
|
</div>
|
2021-08-23 18:43:32 +08:00
|
|
|
<?php
|
2021-08-18 16:09:22 +08:00
|
|
|
install_js_support();
|
2021-08-17 18:36:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* perform step 3
|
|
|
|
*/
|
2021-08-23 18:43:32 +08:00
|
|
|
function install_step_3_perform()
|
|
|
|
{
|
2021-08-17 18:36:54 +08:00
|
|
|
global $installDb;
|
|
|
|
|
2021-08-23 18:43:32 +08:00
|
|
|
$request = \Typecho\Request::getInstance();
|
|
|
|
$defaultPassword = \Typecho\Common::randString(8);
|
2021-08-30 14:52:52 +08:00
|
|
|
$options = \Widget\Options::alloc();
|
2021-08-17 18:36:54 +08:00
|
|
|
|
|
|
|
if (install_is_cli()) {
|
|
|
|
$config = [
|
2021-08-18 16:09:22 +08:00
|
|
|
'userUrl' => $request->getServer('TYPECHO_SITE_URL'),
|
2021-08-17 18:36:54 +08:00
|
|
|
'userName' => $request->getServer('TYPECHO_USER_NAME', 'typecho'),
|
|
|
|
'userPassword' => $request->getServer('TYPECHO_USER_PASSWORD'),
|
2021-08-18 00:41:48 +08:00
|
|
|
'userMail' => $request->getServer('TYPECHO_USER_MAIL', 'admin@localhost.local')
|
2021-08-17 18:36:54 +08:00
|
|
|
];
|
|
|
|
} else {
|
|
|
|
$config = $request->from([
|
|
|
|
'userUrl',
|
|
|
|
'userName',
|
|
|
|
'userPassword',
|
|
|
|
'userMail',
|
|
|
|
]);
|
|
|
|
}
|
|
|
|
|
2021-08-23 18:43:32 +08:00
|
|
|
$error = (new \Typecho\Validate())
|
2021-08-18 16:09:22 +08:00
|
|
|
->addRule('userUrl', 'required', _t('请填写站点地址'))
|
|
|
|
->addRule('userUrl', 'url', _t('请填写一个合法的URL地址'))
|
2021-08-23 18:43:32 +08:00
|
|
|
->addRule('userName', 'required', _t('必须填写用户名称'))
|
2021-08-18 16:09:22 +08:00
|
|
|
->addRule('userName', 'xssCheck', _t('请不要在用户名中使用特殊字符'))
|
2021-08-17 18:36:54 +08:00
|
|
|
->addRule('userName', 'maxLength', _t('用户名长度超过限制, 请不要超过 32 个字符'), 32)
|
2021-08-18 16:09:22 +08:00
|
|
|
->addRule('userMail', 'required', _t('必须填写电子邮箱'))
|
|
|
|
->addRule('userMail', 'email', _t('电子邮箱格式错误'))
|
2021-08-17 18:36:54 +08:00
|
|
|
->addRule('userMail', 'maxLength', _t('邮箱长度超过限制, 请不要超过 200 个字符'), 200)
|
|
|
|
->run($config);
|
|
|
|
|
|
|
|
if (!empty($error)) {
|
|
|
|
install_raise_error($error);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (empty($config['userPassword'])) {
|
|
|
|
$config['userPassword'] = $defaultPassword;
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
|
|
|
// write user
|
2021-09-01 18:27:03 +08:00
|
|
|
$hasher = new \Utils\PasswordHash(8, true);
|
2021-08-17 18:36:54 +08:00
|
|
|
$installDb->query(
|
|
|
|
$installDb->insert('table.users')->rows([
|
|
|
|
'name' => $config['userName'],
|
2021-09-01 18:27:03 +08:00
|
|
|
'password' => $hasher->hashPassword($config['userPassword']),
|
2021-08-17 18:36:54 +08:00
|
|
|
'mail' => $config['userMail'],
|
2021-09-15 14:33:23 +08:00
|
|
|
'url' => $config['userUrl'],
|
2021-08-17 18:36:54 +08:00
|
|
|
'screenName' => $config['userName'],
|
|
|
|
'group' => 'administrator',
|
2021-08-23 18:43:32 +08:00
|
|
|
'created' => \Typecho\Date::time()
|
2021-08-17 18:36:54 +08:00
|
|
|
])
|
|
|
|
);
|
|
|
|
|
|
|
|
// write category
|
|
|
|
$installDb->query(
|
|
|
|
$installDb->insert('table.metas')
|
|
|
|
->rows([
|
|
|
|
'name' => _t('默认分类'),
|
|
|
|
'slug' => 'default',
|
|
|
|
'type' => 'category',
|
2021-08-20 17:53:02 +08:00
|
|
|
'description' => _t('只是一个默认分类'),
|
|
|
|
'count' => 1
|
2021-08-17 18:36:54 +08:00
|
|
|
])
|
|
|
|
);
|
|
|
|
|
|
|
|
$installDb->query($installDb->insert('table.relationships')->rows(['cid' => 1, 'mid' => 1]));
|
|
|
|
|
|
|
|
// write first page and post
|
|
|
|
$installDb->query(
|
|
|
|
$installDb->insert('table.contents')->rows([
|
|
|
|
'title' => _t('欢迎使用 Typecho'),
|
2021-08-23 18:43:32 +08:00
|
|
|
'slug' => 'start', 'created' => \Typecho\Date::time(),
|
|
|
|
'modified' => \Typecho\Date::time(),
|
2021-08-17 18:36:54 +08:00
|
|
|
'text' => '<!--markdown-->' . _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([
|
|
|
|
'title' => _t('关于'),
|
|
|
|
'slug' => 'start-page',
|
2021-08-23 18:43:32 +08:00
|
|
|
'created' => \Typecho\Date::time(),
|
|
|
|
'modified' => \Typecho\Date::time(),
|
2021-08-17 18:36:54 +08:00
|
|
|
'text' => '<!--markdown-->' . _t('本页面由 Typecho 创建, 这只是个测试页面.'),
|
|
|
|
'authorId' => 1,
|
|
|
|
'order' => 0,
|
|
|
|
'type' => 'page',
|
|
|
|
'status' => 'publish',
|
|
|
|
'commentsNum' => 0,
|
|
|
|
'allowComment' => 1,
|
|
|
|
'allowPing' => 1,
|
|
|
|
'allowFeed' => 1,
|
|
|
|
'parent' => 0
|
|
|
|
])
|
|
|
|
);
|
|
|
|
|
|
|
|
// write comment
|
|
|
|
$installDb->query(
|
|
|
|
$installDb->insert('table.comments')->rows([
|
2021-08-23 18:43:32 +08:00
|
|
|
'cid' => 1, 'created' => \Typecho\Date::time(),
|
2021-08-17 18:36:54 +08:00
|
|
|
'author' => 'Typecho',
|
|
|
|
'ownerId' => 1,
|
2021-10-13 14:33:28 +08:00
|
|
|
'url' => 'https://typecho.org',
|
2021-08-17 18:36:54 +08:00
|
|
|
'ip' => '127.0.0.1',
|
|
|
|
'agent' => $options->generator,
|
2023-10-31 05:30:54 +02:00
|
|
|
'text' => _t('欢迎加入 Typecho 大家族'),
|
2021-08-17 18:36:54 +08:00
|
|
|
'type' => 'comment',
|
|
|
|
'status' => 'approved',
|
|
|
|
'parent' => 0
|
|
|
|
])
|
|
|
|
);
|
2021-09-17 15:06:05 +08:00
|
|
|
|
|
|
|
// write options
|
|
|
|
foreach (install_get_default_options() as $key => $value) {
|
|
|
|
// mark installing finished
|
|
|
|
if ($key == 'installed') {
|
|
|
|
$value = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
$installDb->query(
|
|
|
|
$installDb->insert('table.options')->rows(['name' => $key, 'user' => 0, 'value' => $value])
|
|
|
|
);
|
|
|
|
}
|
2021-08-23 18:43:32 +08:00
|
|
|
} catch (\Typecho\Db\Exception $e) {
|
2021-08-17 18:36:54 +08:00
|
|
|
install_raise_error($e->getMessage());
|
|
|
|
}
|
|
|
|
|
2021-08-18 16:09:22 +08:00
|
|
|
$parts = parse_url($options->loginAction);
|
|
|
|
$parts['query'] = http_build_query([
|
|
|
|
'name' => $config['userName'],
|
|
|
|
'password' => $config['userPassword'],
|
|
|
|
'referer' => $options->adminUrl
|
|
|
|
]);
|
2021-08-23 18:43:32 +08:00
|
|
|
$loginUrl = \Typecho\Common::buildUrl($parts);
|
2021-08-18 16:09:22 +08:00
|
|
|
|
2021-08-17 18:36:54 +08:00
|
|
|
install_success(0, [
|
|
|
|
$config['userName'],
|
2021-08-18 16:09:22 +08:00
|
|
|
$config['userPassword'],
|
2021-08-30 14:52:52 +08:00
|
|
|
\Widget\Security::alloc()->getTokenUrl($loginUrl, $request->getReferer()),
|
2021-09-15 14:33:23 +08:00
|
|
|
$config['userUrl']
|
2021-08-17 18:36:54 +08:00
|
|
|
]);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* dispatch install action
|
|
|
|
*
|
|
|
|
*/
|
2021-08-23 18:43:32 +08:00
|
|
|
function install_dispatch()
|
|
|
|
{
|
2021-08-17 22:44:06 +08:00
|
|
|
// disable root url on cli mode
|
|
|
|
if (install_is_cli()) {
|
|
|
|
define('__TYPECHO_ROOT_URL__', 'http://localhost');
|
|
|
|
}
|
|
|
|
|
2021-08-17 18:36:54 +08:00
|
|
|
// init default options
|
2021-08-30 14:52:52 +08:00
|
|
|
$options = \Widget\Options::alloc(install_get_default_options());
|
|
|
|
\Widget\Init::alloc();
|
2021-08-17 18:36:54 +08:00
|
|
|
|
2021-09-17 15:15:54 +08:00
|
|
|
// display version
|
|
|
|
if (install_is_cli()) {
|
|
|
|
echo $options->generator . "\n";
|
|
|
|
echo 'PHP ' . PHP_VERSION . "\n";
|
|
|
|
}
|
|
|
|
|
2021-08-17 18:36:54 +08:00
|
|
|
// install finished yet
|
|
|
|
if (
|
|
|
|
install_check('config')
|
|
|
|
&& install_check('db_structure')
|
|
|
|
&& install_check('db_data')
|
|
|
|
) {
|
2021-08-19 11:15:53 +08:00
|
|
|
// redirect to siteUrl if not cli
|
|
|
|
if (!install_is_cli()) {
|
2021-08-26 15:00:38 +08:00
|
|
|
install_redirect($options->siteUrl);
|
2021-08-19 11:15:53 +08:00
|
|
|
}
|
|
|
|
|
2021-08-18 00:47:34 +08:00
|
|
|
exit(1);
|
2021-08-17 18:36:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (install_is_cli()) {
|
2021-08-26 18:25:43 +08:00
|
|
|
install_step_1_perform();
|
2021-08-17 18:36:54 +08:00
|
|
|
} else {
|
2021-08-23 18:43:32 +08:00
|
|
|
$request = \Typecho\Request::getInstance();
|
2021-08-17 18:36:54 +08:00
|
|
|
$step = $request->get('step');
|
|
|
|
|
|
|
|
$action = 1;
|
|
|
|
|
|
|
|
switch (true) {
|
|
|
|
case $step == 2:
|
|
|
|
if (!install_check('db_structure')) {
|
|
|
|
$action = 2;
|
|
|
|
} else {
|
2021-08-26 15:00:38 +08:00
|
|
|
install_redirect('install.php?step=3');
|
2021-08-17 18:36:54 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case $step == 3:
|
|
|
|
if (install_check('db_structure')) {
|
|
|
|
$action = 3;
|
|
|
|
} else {
|
2021-08-26 15:00:38 +08:00
|
|
|
install_redirect('install.php?step=2');
|
2021-08-17 18:36:54 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
$method = 'install_step_' . $action;
|
|
|
|
|
2021-08-26 15:00:38 +08:00
|
|
|
if ($request->isPost()) {
|
2021-08-17 18:36:54 +08:00
|
|
|
$method .= '_perform';
|
|
|
|
$method();
|
|
|
|
exit;
|
|
|
|
}
|
2021-08-23 18:43:32 +08:00
|
|
|
?>
|
2021-08-17 18:36:54 +08:00
|
|
|
<!DOCTYPE HTML>
|
|
|
|
<html>
|
|
|
|
<head>
|
|
|
|
<meta charset="<?php _e('UTF-8'); ?>" />
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
|
|
|
<title><?php _e('Typecho 安装程序'); ?></title>
|
|
|
|
<link rel="stylesheet" type="text/css" href="<?php $options->adminStaticUrl('css', 'normalize.css') ?>" />
|
|
|
|
<link rel="stylesheet" type="text/css" href="<?php $options->adminStaticUrl('css', 'grid.css') ?>" />
|
|
|
|
<link rel="stylesheet" type="text/css" href="<?php $options->adminStaticUrl('css', 'style.css') ?>" />
|
|
|
|
<link rel="stylesheet" type="text/css" href="<?php $options->adminStaticUrl('css', 'install.css') ?>" />
|
2021-08-18 16:09:22 +08:00
|
|
|
<script src="<?php $options->adminStaticUrl('js', 'jquery.js'); ?>"></script>
|
2021-08-17 18:36:54 +08:00
|
|
|
</head>
|
|
|
|
<body>
|
|
|
|
<div class="body container">
|
2023-03-28 11:57:45 +08:00
|
|
|
<h1><a href="https://typecho.org" target="_blank" class="i-logo">Typecho</a></h1>
|
2021-08-17 18:36:54 +08:00
|
|
|
<?php $method(); ?>
|
|
|
|
</div>
|
|
|
|
</body>
|
|
|
|
</html>
|
2021-08-23 18:43:32 +08:00
|
|
|
<?php
|
2021-08-17 18:36:54 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
install_dispatch();
|