增加站点url设置功能,并且当站点url地址发生变化时,可以让用户以新地址正常登录后台并修改站点url

修正http://forum.typecho.org/viewtopic.php?f=4&t=4708 提到的问题
This commit is contained in:
joyqi 2013-12-20 00:11:34 +08:00
parent 0f822e5bfd
commit 2b9cf7755a
27 changed files with 199 additions and 115 deletions

View File

@ -1,4 +1,4 @@
<?php if(!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
<?php if(!defined('__TYPECHO_ADMIN__')) exit; ?>
<script src="<?php $options->adminUrl('js/jquery.js?v=' . $suffixVersion); ?>"></script>
<script src="<?php $options->adminUrl('js/jquery-ui.js?v=' . $suffixVersion); ?>"></script>
<script src="<?php $options->adminUrl('js/typecho.js?v=' . $suffixVersion); ?>"></script>

View File

@ -3,6 +3,8 @@ if (!defined('__DIR__')) {
define('__DIR__', dirname(__FILE__));
}
define('__TYPECHO_ADMIN__', true);
/** 载入配置文件 */
if (!@include_once __DIR__ . '/../config.inc.php') {
file_exists(__DIR__ . '/../install.php') ? header('Location: ../install.php') : print('Missing Config File');

View File

@ -1,4 +1,4 @@
<?php if(!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
<?php if(!defined('__TYPECHO_ADMIN__')) exit; ?>
<div class="typecho-foot" role="contentinfo">
<div class="copyright">
<a href="http://typecho.org" class="i-logo-s">Typecho</a>

View File

@ -1,3 +1,4 @@
<?php if(!defined('__TYPECHO_ADMIN__')) exit; ?>
<script>
$(document).ready(function () {
// 自定义字段

View File

@ -1,4 +1,4 @@
<?php if(!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
<?php if(!defined('__TYPECHO_ADMIN__')) exit; ?>
<?php
$fields = isset($post) ? $post->getFieldItems() : $page->getFieldItems();
$defaultFields = isset($post) ? $post->getDefaultFieldItems() : $page->getDefaultFieldItems();

View File

@ -1,4 +1,4 @@
<?php if(!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
<?php if(!defined('__TYPECHO_ADMIN__')) exit; ?>
<?php $content = !empty($post) ? $post : $page; if ($options->markdown): ?>
<script src="<?php $options->adminUrl('js/pagedown.js?v=' . $suffixVersion); ?>"></script>
<script src="<?php $options->adminUrl('js/pagedown-extra.js?v=' . $suffixVersion); ?>"></script>

View File

@ -1,4 +1,4 @@
<?php if(!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
<?php if(!defined('__TYPECHO_ADMIN__')) exit; ?>
<?php
if (isset($post) && $post instanceof Typecho_Widget && $post->have()) {
$fileParentContent = $post;

View File

@ -1,4 +1,4 @@
<?php if(!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
<?php if(!defined('__TYPECHO_ADMIN__')) exit; ?>
<?php
if (isset($post) || isset($page)) {

View File

@ -1,4 +1,4 @@
<?php if(!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
<?php if(!defined('__TYPECHO_ADMIN__')) exit; ?>
</body>
</html>
<?php

View File

@ -1,11 +1,11 @@
<?php if(!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
<?php if(!defined('__TYPECHO_ADMIN__')) exit; ?>
<script>
(function () {
$(document).ready(function () {
var error = $('.typecho-option .error:first');
if (error.length > 0) {
$('html,body').scrollTop(error.offset().top);
$('html,body').scrollTop(error.parents('.typecho-option').offset().top);
}
$('form').submit(function () {

View File

@ -1,5 +1,5 @@
<?php
if (!defined('__TYPECHO_ROOT_DIR__')) {
if (!defined('__TYPECHO_ADMIN__')) {
exit;
}

View File

@ -1,4 +1,4 @@
<?php if(!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
<?php if(!defined('__TYPECHO_ADMIN__')) exit; ?>
<div class="typecho-head-nav clearfix" role="navigation">
<nav id="typecho-nav-list">
<?php $menu->output(); ?>

View File

@ -1,4 +1,4 @@
<?php if(!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
<?php if(!defined('__TYPECHO_ADMIN__')) exit; ?>
<div class="colgroup">
<div class="typecho-page-title col-mb-12">
<h2><?php echo $menu->title; ?><?php

View File

@ -1,4 +1,4 @@
<?php if(!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
<?php if(!defined('__TYPECHO_ADMIN__')) exit; ?>
<script>
(function () {
$(document).ready(function () {

View File

@ -11,7 +11,7 @@ include 'menu.php';
<div class="col-mb-12">
<div id="typecho-welcome">
<form action="<?php echo Typecho_Router::url('do', array('action' => 'upgrade', 'widget' => 'Upgrade'),
Typecho_Common::url('index.php', $options->siteUrl)); ?>" method="post">
Typecho_Common::url('index.php', $options->rootUrl)); ?>" method="post">
<h3><?php _e('检测到新版本!'); ?></h3>
<ul>
<li><?php _e('您已经更新了系统程序, 我们还需要执行一些后续步骤来完成升级'); ?></li>

View File

@ -1,4 +1,4 @@
<?php if(!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
<?php if(!defined('__TYPECHO_ADMIN__')) exit; ?>
<?php Typecho_Plugin::factory('admin/write-js.php')->write(); ?>
<?php Typecho_Widget::widget('Widget_Metas_Tag_Cloud', 'sort=count&desc=1&limit=200')->to($tags); ?>

View File

@ -20,7 +20,7 @@
class Typecho_Common
{
/** 程序版本 */
const VERSION = '0.9/13.12.12';
const VERSION = '0.9/13.12.20';
/**
* 缓存的包含路径

View File

@ -29,16 +29,28 @@ class Typecho_Cookie
*/
private static $_prefix = '';
/**
* 路径
*
* @var string
* @access private
*/
private static $_path = '/';
/**
* 设置前缀
*
* @param string $prefix
* @param string $url
* @access public
* @return void
*/
public static function setPrefix($prefix)
public static function setPrefix($url)
{
self::$_prefix = md5($prefix);
self::$_prefix = md5($url);
$parsed = parse_url($url);
/** 在路径后面强制加上斜杠 */
self::$_path = empty($parsed['path']) ? '/' : Typecho_Common::url(NULL, $parsed['path']);
}
/**
@ -74,27 +86,19 @@ class Typecho_Cookie
* @param string $key 指定的参数
* @param mixed $value 设置的值
* @param integer $expire 过期时间,默认为0,表示随会话时间结束
* @param string $url 路径(可以是域名,也可以是地址)
* @return void
*/
public static function set($key, $value, $expire = 0, $url = NULL)
public static function set($key, $value, $expire = 0)
{
$path = '/';
$key = self::$_prefix . $key;
if (!empty($url)) {
$parsed = parse_url($url);
/** 在路径后面强制加上斜杠 */
$path = empty($parsed['path']) ? '/' : Typecho_Common::url(NULL, $parsed['path']);
}
/** 对数组型COOKIE的写入支持 */
if (is_array($value)) {
foreach ($value as $name => $val) {
setrawcookie("{$key}[{$name}]", rawurlencode($val), $expire, $path);
setrawcookie("{$key}[{$name}]", rawurlencode($val), $expire, self::$_path);
}
} else {
setrawcookie($key, rawurlencode($value), $expire, $path);
setrawcookie($key, rawurlencode($value), $expire, self::$_path);
}
$_COOKIE[$key] = $value;
@ -107,28 +111,20 @@ class Typecho_Cookie
* @param string $key 指定的参数
* @return void
*/
public static function delete($key, $url = NULL)
public static function delete($key)
{
$key = self::$_prefix . $key;
if (!isset($_COOKIE[$key])) {
return;
}
$path = '/';
if (!empty($url)) {
$parsed = parse_url($url);
/** 在路径后面强制加上斜杠 */
$path = empty($parsed['path']) ? '/' : Typecho_Common::url(NULL, $parsed['path']);
}
/** 对数组型COOKIE的删除支持 */
if (is_array($_COOKIE[$key])) {
foreach ($_COOKIE[$key] as $name => $val) {
setcookie("{$key}[{$name}]", '', time() - 2592000, $path);
setcookie("{$key}[{$name}]", '', time() - 2592000, self::$_path);
}
} else {
setcookie($key, '', time() - 2592000, $path);
setcookie($key, '', time() - 2592000, self::$_path);
}
unset($_COOKIE[$key]);

View File

@ -47,6 +47,22 @@ class Typecho_Request
*/
private $_requestUri = NULL;
/**
* _requestRoot
*
* @var mixed
* @access private
*/
private $_requestRoot = NULL;
/**
* 获取baseurl
*
* @var string
* @access private
*/
private $_baseUrl = NULL;
/**
* 客户端ip地址
*
@ -305,6 +321,30 @@ class Typecho_Request
$this->_params = array_merge($this->_params, $params);
}
/**
* getRequestRoot
*
* @access public
* @return void
*/
public function getRequestRoot()
{
if (NULL === $this->_requestRoot) {
$root = rtrim(($this->isSecure() ? 'https' : 'http')
. '://' . $_SERVER['HTTP_HOST']
. $this->getBaseUrl(), '/') . '/';
$pos = strrpos($root, '.php/');
if ($pos) {
$root = dirname(substr($root, 0, $pos));
}
$this->_requestRoot = rtrim($root, '/');
}
return $this->_requestRoot;
}
/**
* 获取当前请求url
*
@ -362,6 +402,69 @@ class Typecho_Request
return $this->_requestUri = $requestUri;
}
/**
* getBaseUrl
*
* @access public
* @return string
*/
public function getBaseUrl()
{
if (NULL !== $this->_baseUrl) {
return $this->_baseUrl;
}
//处理baseUrl
$filename = (isset($_SERVER['SCRIPT_FILENAME'])) ? basename($_SERVER['SCRIPT_FILENAME']) : '';
if (isset($_SERVER['SCRIPT_NAME']) && basename($_SERVER['SCRIPT_NAME']) === $filename) {
$baseUrl = $_SERVER['SCRIPT_NAME'];
} elseif (isset($_SERVER['PHP_SELF']) && basename($_SERVER['PHP_SELF']) === $filename) {
$baseUrl = $_SERVER['PHP_SELF'];
} elseif (isset($_SERVER['ORIG_SCRIPT_NAME']) && basename($_SERVER['ORIG_SCRIPT_NAME']) === $filename) {
$baseUrl = $_SERVER['ORIG_SCRIPT_NAME']; // 1and1 shared hosting compatibility
} else {
// Backtrack up the script_filename to find the portion matching
// php_self
$path = isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : '';
$file = isset($_SERVER['SCRIPT_FILENAME']) ? $_SERVER['SCRIPT_FILENAME'] : '';
$segs = explode('/', trim($file, '/'));
$segs = array_reverse($segs);
$index = 0;
$last = count($segs);
$baseUrl = '';
do {
$seg = $segs[$index];
$baseUrl = '/' . $seg . $baseUrl;
++$index;
} while (($last > $index) && (false !== ($pos = strpos($path, $baseUrl))) && (0 != $pos));
}
// Does the baseUrl have anything in common with the request_uri?
$finalBaseUrl = NULL;
$requestUri = $this->getRequestUri();
if (0 === strpos($requestUri, $baseUrl)) {
// full $baseUrl matches
$finalBaseUrl = $baseUrl;
} else if (0 === strpos($requestUri, dirname($baseUrl))) {
// directory portion of $baseUrl matches
$finalBaseUrl = rtrim(dirname($baseUrl), '/');
} else if (!strpos($requestUri, basename($baseUrl))) {
// no match whatsoever; set it blank
$finalBaseUrl = '';
} else if ((strlen($requestUri) >= strlen($baseUrl))
&& ((false !== ($pos = strpos($requestUri, $baseUrl))) && ($pos !== 0)))
{
// If using mod_rewrite or ISAPI_Rewrite strip the script filename
// out of baseUrl. $pos !== 0 makes sure it is not matching a value
// from PATH_INFO or QUERY_STRING
$baseUrl = substr($requestUri, 0, $pos + strlen($baseUrl));
}
return ($this->_baseUrl = (NULL === $finalBaseUrl) ? rtrim($baseUrl, '/') : $finalBaseUrl);
}
/**
* 根据当前uri构造指定参数的uri
*
@ -418,55 +521,7 @@ class Typecho_Request
//处理requestUri
$requestUri = $this->getRequestUri();
//处理baseUrl
$filename = (isset($_SERVER['SCRIPT_FILENAME'])) ? basename($_SERVER['SCRIPT_FILENAME']) : '';
if (isset($_SERVER['SCRIPT_NAME']) && basename($_SERVER['SCRIPT_NAME']) === $filename) {
$baseUrl = $_SERVER['SCRIPT_NAME'];
} elseif (isset($_SERVER['PHP_SELF']) && basename($_SERVER['PHP_SELF']) === $filename) {
$baseUrl = $_SERVER['PHP_SELF'];
} elseif (isset($_SERVER['ORIG_SCRIPT_NAME']) && basename($_SERVER['ORIG_SCRIPT_NAME']) === $filename) {
$baseUrl = $_SERVER['ORIG_SCRIPT_NAME']; // 1and1 shared hosting compatibility
} else {
// Backtrack up the script_filename to find the portion matching
// php_self
$path = isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : '';
$file = isset($_SERVER['SCRIPT_FILENAME']) ? $_SERVER['SCRIPT_FILENAME'] : '';
$segs = explode('/', trim($file, '/'));
$segs = array_reverse($segs);
$index = 0;
$last = count($segs);
$baseUrl = '';
do {
$seg = $segs[$index];
$baseUrl = '/' . $seg . $baseUrl;
++$index;
} while (($last > $index) && (false !== ($pos = strpos($path, $baseUrl))) && (0 != $pos));
}
// Does the baseUrl have anything in common with the request_uri?
$finalBaseUrl = NULL;
if (0 === strpos($requestUri, $baseUrl)) {
// full $baseUrl matches
$finalBaseUrl = $baseUrl;
} else if (0 === strpos($requestUri, dirname($baseUrl))) {
// directory portion of $baseUrl matches
$finalBaseUrl = rtrim(dirname($baseUrl), '/');
} else if (!strpos($requestUri, basename($baseUrl))) {
// no match whatsoever; set it blank
$finalBaseUrl = '';
} else if ((strlen($requestUri) >= strlen($baseUrl))
&& ((false !== ($pos = strpos($requestUri, $baseUrl))) && ($pos !== 0)))
{
// If using mod_rewrite or ISAPI_Rewrite strip the script filename
// out of baseUrl. $pos !== 0 makes sure it is not matching a value
// from PATH_INFO or QUERY_STRING
$baseUrl = substr($requestUri, 0, $pos + strlen($baseUrl));
}
$finalBaseUrl = (NULL === $finalBaseUrl) ? rtrim($baseUrl, '/') : $finalBaseUrl;
$finalBaseUrl = $this->getBaseUrl();
// Remove the query string from REQUEST_URI
if ($pos = strpos($requestUri, '?')) {

View File

@ -1087,5 +1087,22 @@ Typecho_Date::setTimezoneOffset($options->timezone);
->rows(array('name' => 'frontArchive', 'user' => 0, 'value' => 0)));
}
}
/**
* v0_9r13_12_20
*
* @param mixed $db
* @param mixed $options
* @access public
* @return void
*/
public function v0_9r13_12_20($db, $options)
{
$commentsWhitelist = $db->fetchRow($db->select()->from('table.options')->where('name = ?', 'commentsWhitelist'));
if (empty($commentsWhitelist)) {
$db->query($db->insert('table.options')
->rows(array('name' => 'commentsWhitelist', 'user' => 0, 'value' => 0)));
}
}
}

View File

@ -26,7 +26,7 @@ class Widget_Init extends Typecho_Widget
$options = $this->widget('Widget_Options');
/** cookie初始化 */
Typecho_Cookie::setPrefix($options->siteUrl);
Typecho_Cookie::setPrefix($options->rootUrl);
/** 初始化charset */
Typecho_Common::$charset = $options->charset;

View File

@ -33,8 +33,7 @@ class Widget_Notice extends Typecho_Widget
{
$this->highlight = $theId;
Typecho_Cookie::set('__typecho_notice_highlight', $theId,
$this->widget('Widget_Options')->gmtTime + $this->widget('Widget_Options')->timezone + 86400,
$this->widget('Widget_Options')->siteUrl);
$this->widget('Widget_Options')->gmtTime + $this->widget('Widget_Options')->timezone + 86400);
}
/**
@ -64,10 +63,8 @@ class Widget_Notice extends Typecho_Widget
}
Typecho_Cookie::set('__typecho_notice', json_encode($notice),
$this->widget('Widget_Options')->gmtTime + $this->widget('Widget_Options')->timezone + 86400,
$this->widget('Widget_Options')->siteUrl);
$this->widget('Widget_Options')->gmtTime + $this->widget('Widget_Options')->timezone + 86400);
Typecho_Cookie::set('__typecho_notice_type', $type,
$this->widget('Widget_Options')->gmtTime + $this->widget('Widget_Options')->timezone + 86400,
$this->widget('Widget_Options')->siteUrl);
$this->widget('Widget_Options')->gmtTime + $this->widget('Widget_Options')->timezone + 86400);
}
}

View File

@ -145,7 +145,7 @@ class Widget_Options extends Typecho_Widget
*/
protected function ___index()
{
return $this->rewrite ? $this->siteUrl : Typecho_Common::url('index.php', $this->siteUrl);
return $this->rewrite ? $this->rootUrl : Typecho_Common::url('index.php', $this->rootUrl);
}
/**
@ -179,7 +179,7 @@ class Widget_Options extends Typecho_Widget
protected function ___adminUrl()
{
return Typecho_Common::url(defined('__TYPECHO_ADMIN_DIR__') ?
__TYPECHO_ADMIN_DIR__ : '/admin/', $this->siteUrl);
__TYPECHO_ADMIN_DIR__ : '/admin/', $this->rootUrl);
}
/**
@ -202,7 +202,7 @@ class Widget_Options extends Typecho_Widget
protected function ___loginAction()
{
return Typecho_Router::url('do', array('action' => 'login', 'widget' => 'Login'),
Typecho_Common::url('index.php', $this->siteUrl));
Typecho_Common::url('index.php', $this->rootUrl));
}
/**
@ -353,9 +353,17 @@ class Widget_Options extends Typecho_Widget
$this->stack[] = &$this->row;
/** 初始化站点信息 */
$this->originalSiteUrl = $this->siteUrl;
$this->siteUrl = Typecho_Common::url(NULL, $this->siteUrl);
$this->plugins = unserialize($this->plugins);
/** 动态获取根目录 */
$this->rootUrl = $this->request->getRequestRoot();
if (defined('__TYPECHO_ADMIN__')) {
$adminDir = '/' . trim(defined('__TYPECHO_ADMIN_DIR__') ? __TYPECHO_ADMIN_DIR__ : '/admin/', '/');
$this->rootUrl = substr($this->rootUrl, 0, - strlen($adminDir));
}
/** 增加对SSL连接的支持 */
if ($this->request->isSecure() && 0 === strpos($this->siteUrl, 'http://')) {
$this->siteUrl = substr_replace($this->siteUrl, 'https', 0, 4);

View File

@ -34,10 +34,20 @@ class Widget_Options_General extends Widget_Abstract_Options implements Widget_I
/** 站点名称 */
$title = new Typecho_Widget_Helper_Form_Element_Text('title', NULL, $this->options->title, _t('站点名称'), _t('站点的名称将显示在网页的标题处.'));
$form->addInput($title);
$title->input->setAttribute('class', 'w-40');
$form->addInput($title->addRule('required', _t('请填写站点名称')));
/** 站点地址 */
$siteUrl = new Typecho_Widget_Helper_Form_Element_Text('siteUrl', NULL, $this->options->originalSiteUrl, _t('站点地址'), _t('站点地址主要用于生成内容的永久链接.')
. ($this->options->originalSiteUrl == $this->options->rootUrl ?
'' : '</p><p class="message notice mono">' . _t('当前地址 <strong>%s</strong> 与上述设定值不一致',
$this->options->rootUrl)));
$siteUrl->input->setAttribute('class', 'w-60 mono');
$form->addInput($siteUrl->addRule('required', _t('请填写站点地址'))
->addRule('url', _t('请填写一个合法的URL地址')));
/** 站点描述 */
$description = new Typecho_Widget_Helper_Form_Element_Textarea('description', NULL, $this->options->description, _t('站点描述'), _t('站点描述将显示在网页代码的头部.'));
$description = new Typecho_Widget_Helper_Form_Element_Text('description', NULL, $this->options->description, _t('站点描述'), _t('站点描述将显示在网页代码的头部.'));
$form->addInput($description);
/** 关键词 */
@ -137,8 +147,9 @@ class Widget_Options_General extends Widget_Abstract_Options implements Widget_I
$this->response->goBack();
}
$settings = $this->request->from('title', 'description', 'keywords', 'allowRegister', 'timezone', 'attachmentTypes');
$settings = $this->request->from('title', 'siteUrl', 'description', 'keywords', 'allowRegister', 'timezone', 'attachmentTypes');
$settings['siteUrl'] = rtrim('/', $settings['url']);
$attachmentTypes = array();
if ($this->isEnableByCheckbox($settings['attachmentTypes'], '@image@')) {
$attachmentTypes[] = '@image@';

View File

@ -201,7 +201,7 @@ RewriteRule . {$basePath}index.php [L]
public function form()
{
/** 构建表格 */
$form = new Typecho_Widget_Helper_Form(Typecho_Common::url('index.php/action/options-permalink', $this->options->siteUrl),
$form = new Typecho_Widget_Helper_Form(Typecho_Common::url('index.php/action/options-permalink', $this->options->rootUrl),
Typecho_Widget_Helper_Form::POST_METHOD);
/** 是否使用地址重写功能 */

View File

@ -134,8 +134,8 @@ class Widget_Service extends Widget_Abstract_Options implements Widget_Interface
$input['trackback'] = $trackback;
}
$client->setCookie('__typecho_uid', Typecho_Cookie::get('__typecho_uid'), 0, $this->options->siteUrl)
->setCookie('__typecho_authCode', Typecho_Cookie::get('__typecho_authCode'), 0, $this->options->siteUrl)
$client->setCookie('__typecho_uid', Typecho_Cookie::get('__typecho_uid'))
->setCookie('__typecho_authCode', Typecho_Cookie::get('__typecho_authCode'))
->setHeader('User-Agent', $this->options->generator)
->setTimeout(3)
->setData($input)

View File

@ -135,9 +135,8 @@ class Widget_User extends Typecho_Widget
$authCode = sha1(Typecho_Common::randString(20));
$user['authCode'] = $authCode;
Typecho_Cookie::set('__typecho_uid', $user['uid'], $expire, $this->options->siteUrl);
Typecho_Cookie::set('__typecho_authCode', Typecho_Common::hash($authCode),
$expire, $this->options->siteUrl);
Typecho_Cookie::set('__typecho_uid', $user['uid'], $expire);
Typecho_Cookie::set('__typecho_authCode', Typecho_Common::hash($authCode), $expire);
//更新最后登录时间以及验证码
$this->db->query($this->db
@ -196,10 +195,8 @@ class Widget_User extends Typecho_Widget
return;
}
Typecho_Cookie::delete('__typecho_uid', $this->options->siteUrl);
Typecho_Cookie::delete('__typecho_authCode', $this->options->siteUrl);
Typecho_Cookie::delete('__typecho_feed');
Typecho_Cookie::delete('__typecho_check_version');
Typecho_Cookie::delete('__typecho_uid');
Typecho_Cookie::delete('__typecho_authCode');
}
/**