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_Mysqli::isAvailable()) { $drivers['Mysqli'] = _t('Mysql 原生函数适配器'); } if (Typecho_Db_Adapter_SQLite::isAvailable()) { $drivers['SQLite'] = _t('SQLite 原生函数适配器 (SQLite 2.x)'); } if (Typecho_Db_Adapter_Pgsql::isAvailable()) { $drivers['Pgsql'] = _t('Pgsql 原生函数适配器'); } if (Typecho_Db_Adapter_Pdo_Mysql::isAvailable()) { $drivers['Pdo_Mysql'] = _t('Pdo 驱动 Mysql 适配器'); } if (Typecho_Db_Adapter_Pdo_SQLite::isAvailable()) { $drivers['Pdo_SQLite'] = _t('Pdo 驱动 SQLite 适配器 (SQLite 3.x)'); } if (Typecho_Db_Adapter_Pdo_Pgsql::isAvailable()) { $drivers['Pdo_Pgsql'] = _t('Pdo 驱动 PostgreSql 适配器'); } return $drivers; } /** * 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; } 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)) { echo implode("\n", $config); } } else { Typecho_Response::getInstance()->throwJson([ 'success' => 1, 'message' => $step, 'config' => $config ]); } } function install_ajax_support() { $options = Typecho_Widget::widget('Widget_Options'); ?>