getServer('TYPECHO_LANG'); if (!empty($serverLang)) { return $serverLang; } 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); } } /** * get site url * * @return string */ function install_get_site_url(): string { $serverSiteUrl = Typecho_Request::getInstance()->getServer('TYPECHO_SITE_URL'); if (!empty($serverSiteUrl)) { return $serverSiteUrl; } else { $request = Typecho_Request::getInstance(); return $request->get('userUrl', $request->getRequestRoot()); } } /** * detect cli mode * * @return bool */ function install_is_cli(): bool { return php_sapi_name() == 'cli'; } /** * list all default options * * @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_is_cli() ? 'http://localhost' : 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 ]; } /** * get database driver type * * @param string $driver * @return string */ function install_get_db_type(string $driver): string { $parts = explode('_', $driver); return $driver == 'Mysqli' ? 'Mysql' : array_pop($parts); } /** * list all available database drivers * * @return array */ function install_get_db_drivers(): array { $drivers = []; 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 适配器'); } 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 原生函数适配器'); } return $drivers; } /** * get current db driver * * @return string */ function install_get_current_db_driver(): string { global $installDb; if (empty($installDb)) { $driver = Typecho_Request::getInstance()->get('driver'); $drivers = install_get_db_drivers(); if (empty($driver) || !isset($drivers[$driver])) { return key($drivers); } return $driver; } else { return $installDb->getAdapterName(); } } /** * generate config file * * @param string $adapter * @param string $dbPrefix * @param array $dbConfig * @return string */ function install_config_file(string $adapter, string $dbPrefix, array $dbConfig): string { global $configWritten; $lines = array_slice(file(__FILE__), 1, 26); $lines[] = " /** 定义数据库参数 */ \$db = new Typecho_Db('{$adapter}', '{$dbPrefix}'); \$db->addServer(" . (var_export($dbConfig, true)) . ", Typecho_Db::READ | Typecho_Db::WRITE); Typecho_Db::set(\$db); "; $code = implode('', $lines); $configWritten = @file_put_contents(__TYPECHO_ROOT_DIR__ . '/config.inc.php', $code) !== false; return $code; } /** * remove config file if written */ function install_remove_config_file() { global $configWritten; if ($configWritten) { unlink(__TYPECHO_ROOT_DIR__ . '/config.inc.php'); } } /** * check install * * @param string $type * @return bool */ function install_check(string $type): bool { 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 $values = $installDb->fetchAll($installDb->select()->from('table.options') ->where('user = 0')); if ($type == 'db_data' && empty($values)) { return false; } } catch (Typecho_Db_Exception $e) { return false; } return true; default: return false; } } /** * raise install error * * @param mixed $error * @param mixed $config */ function install_raise_error($error, $config = null) { if (install_is_cli()) { if (is_array($error)) { foreach ($error as $key => $value) { echo (is_int($key) ? '' : $key . ': ') . $value . "\n"; } } else { echo $error . "\n"; } exit(1); } else { Typecho_Response::getInstance()->throwJson([ 'success' => 0, 'message' => is_string($error) ? nl2br($error) : $error, 'config' => $config ]); } } /** * @param $step * @param array|null $config */ function install_success($step, ?array $config = null) { if (install_is_cli()) { if ($step > 0) { $method = 'install_step_' . $step . '_perform'; $method(); } if (!empty($config)) { [$userName, $userPassword] = $config; echo _t('安装成功') . "\n"; echo _t('您的用户名是') . " {$userName}\n"; echo _t('您的密码是') . " {$userPassword}\n"; } exit(0); } else { Typecho_Response::getInstance()->throwJson([ 'success' => 1, 'message' => $step, 'config' => $config ]); } } /** * add ajax support * * @throws Typecho_Exception */ function install_ajax_support() { $options = Typecho_Widget::widget('Widget_Options'); ?>

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

1): ?>

getConfig(Typecho_Db::WRITE)->toArray(); $config['prefix'] = $installDb->getPrefix(); $config['adapter'] = $adapter; } ?>

[ 'dbHost' => 'localhost', 'dbPort' => 3306, 'dbUser' => null, 'dbPassword' => null, 'dbCharset' => 'utf8mb4', 'dbDatabase' => null, 'dbEngine' => 'InnoDB' ], 'Pgsql' => [ 'dbHost' => 'localhost', 'dbPort' => 5432, 'dbUser' => null, 'dbPassword' => null, 'dbCharset' => 'utf8', 'dbDatabase' => null, ], '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'), 'dbPrefix' => $request->getServer('TYPECHO_DB_PREFIX', 'typecho_'), 'dbAdapter' => $request->getServer('TYPECHO_DB_ADAPTER', install_get_current_db_driver()), 'dbNext' => $request->getServer('TYPECHO_DB_NEXT', 'none') ]; } else { $config = $request->from([ 'dbHost', 'dbUser', 'dbPassword', 'dbCharset', 'dbPort', 'dbDatabase', 'dbFile', 'dbDsn', 'dbEngine', 'dbPrefix', 'dbAdapter', 'dbNext' ]); } $error = (new Typecho_Validate()) ->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('确认您的配置')) ->addRule('dbNext', 'enum', _t('确认您的配置'), ['none', 'delete', 'keep']) ->run($config); if (!empty($error)) { install_raise_error($error); } $type = install_get_db_type($config['dbAdapter']); $dbConfig = []; foreach ($configMap[$type] as $key => $value) { $config[$key] = $config[$key] === null ? (install_is_cli() ? $value : null) : $config[$key]; } switch ($type) { case 'Mysql': $error = (new Typecho_Validate()) ->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']) ->run($config); break; case 'Pgsql': $error = (new Typecho_Validate()) ->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('确认您的配置')) ->run($config); break; case 'SQLite': $error = (new Typecho_Validate()) ->addRule('dbFile', 'required', _t('确认您的配置')) ->run($config); break; default: install_raise_error(_t('确认您的配置')); break; } if (!empty($error)) { install_raise_error($error); } foreach ($configMap[$type] as $key => $value) { $dbConfig[strtolower(substr($key, 2))] = $config[$key]; } if (empty($installDb)) { // detect db config try { $installDb = new Typecho_Db($config['dbAdapter'], $config['dbPrefix']); $installDb->addServer($dbConfig, Typecho_Db::READ | Typecho_Db::WRITE); $installDb->query('SELECT 1=1'); } catch (Typecho_Db_Adapter_Exception $e) { install_raise_error(_t('对不起, 无法连接数据库, 请先检查数据库配置再继续进行安装')); } catch (Typecho_Db_Exception $e) { install_raise_error(_t('安装程序捕捉到以下错误: " %s ". 程序被终止, 请检查您的配置信息.', $e->getMessage())); } $code = install_config_file($config['dbAdapter'], $config['dbPrefix'], $dbConfig); if (!install_check('config')) { install_raise_error( _t('安装程序无法自动创建 config.inc.php 文件') . "\n" . _t('您可以在网站根目录下手动创建 config.inc.php 文件, 并复制如下代码至其中') , [ 'code' => $code ]); } } // delete exists db if($config['dbNext'] == 'delete') { $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) { if ($type == 'Mysql') { $installDb->query("DROP TABLE IF EXISTS `{$table}`"); } elseif ($type == 'Pgsql') { $installDb->query("DROP TABLE {$table}"); } elseif ($type == 'SQLite') { $installDb->query("DROP TABLE {$table}"); } } } catch (Typecho_Db_Exception $e) { 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) { $installDb->query($script, Typecho_Db::WRITE); } } } catch (Typecho_Db_Exception $e) { $code = $e->getCode(); if(('Mysql' == $type && (1050 == $code || '42S01' == $code)) || ('SQLite' == $type && ('HY000' == $code || 1 == $code)) || ('Pgsql' == $type && '42P07' == $code)) { if ($config['dbNext'] == 'keep') { if (install_check('db_data')) { install_success(0); } else { install_success(3); } } elseif ($config['dbNext'] == 'none') { install_remove_config_file(); install_raise_error(_t('安装程序检查到原有数据表已经存在.'), [ 'delete' => _t('删除原有数据'), 'keep' => _t('使用原有数据') ]); } } else { install_remove_config_file(); install_raise_error(_t('安装程序捕捉到以下错误: "%s". 程序被终止, 请检查您的配置信息.', $e->getMessage())); } } install_success(3); } /** * display step 3 */ function install_step_3() { $options = Typecho_Widget::widget('Widget_Options'); ?>

$request->getServer('TYPECHO_SITE_URL', 'http://localhost'), 'userName' => $request->getServer('TYPECHO_USER_NAME', 'typecho'), 'userPassword' => $request->getServer('TYPECHO_USER_PASSWORD'), 'userMail' => $request->getServer('TYPECHO_USER_MAIL', 'admin@localhost.local') ]; } else { $config = $request->from([ 'userUrl', 'userName', 'userPassword', 'userMail', ]); } $error = (new Typecho_Validate()) ->addRule('userUrl', 'required', _t('请填写您的网站地址')) ->addRule('userUrl', 'url', _t('请填写您的网站地址')) ->addRule('userName', 'required', _t('请填写您的用户名')) ->addRule('userName', 'maxLength', _t('用户名长度超过限制, 请不要超过 32 个字符'), 32) ->addRule('userMail', 'required', _t('请填写您的邮箱地址')) ->addRule('userMail', 'email', _t('请填写您的邮箱地址')) ->addRule('userMail', 'maxLength', _t('邮箱长度超过限制, 请不要超过 200 个字符'), 200) ->run($config); if (!empty($error)) { install_raise_error($error); } if (empty($config['userPassword'])) { $config['userPassword'] = $defaultPassword; } try { // write options foreach (install_get_default_options() as $key => $value) { $installDb->query( $installDb->insert('table.options')->rows(['name' => $key, 'user' => 0, 'value' => $value]) ); } // write user $hasher = new PasswordHash(8, true); $installDb->query( $installDb->insert('table.users')->rows([ 'name' => $config['userName'], 'password' => $hasher->HashPassword($config['userPassword']), 'mail' => $config['userMail'], 'url' => $options->siteUrl, 'screenName' => $config['userName'], 'group' => 'administrator', 'created' => Typecho_Date::time() ]) ); // write category $installDb->query( $installDb->insert('table.metas') ->rows([ 'name' => _t('默认分类'), 'slug' => 'default', 'type' => 'category', 'description' => _t('只是一个默认分类') ]) ); $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'), '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([ '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 ]) ); // write comment $installDb->query( $installDb->insert('table.comments')->rows([ '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 ]) ); } catch (Typecho_Db_Exception $e) { install_raise_error($e->getMessage()); } install_success(0, [ $config['userName'], $config['userPassword'] ]); } /** * dispatch install action * * @throws Typecho_Exception */ function install_dispatch() { // disable root url on cli mode if (install_is_cli()) { define('__TYPECHO_ROOT_URL__', 'http://localhost'); } // init default options $options = Typecho_Widget::widget('Widget_Options', install_get_default_options()); Typecho_Widget::widget('Widget_Init'); // install finished yet if ( install_check('config') && install_check('db_structure') && install_check('db_data') ) { exit; } if (install_is_cli()) { install_step_2_perform(); } else { $request = Typecho_Request::getInstance(); $response = Typecho_Response::getInstance(); $step = $request->get('step'); $action = 1; switch (true) { case $step == 2: if (!install_check('db_structure')) { $action = 2; } else { $response->redirect('install.php?step=3'); } break; case $step == 3: if (install_check('db_structure')) { $action = 3; } else { $response->redirect('install.php?step=2'); } break; default: break; } $method = 'install_step_' . $action; if ($request->isPost() && $action > 1) { $method .= '_perform'; $method(); exit; } ?> <?php _e('Typecho 安装程序'); ?>

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): ?>