This commit is contained in:
joyqi
2018-01-29 18:40:43 +08:00
parent 82212edba0
commit 02dd3f997f
19 changed files with 293 additions and 18 deletions

View File

@@ -100,6 +100,10 @@
t.attr('target', '_blank');
});
}
$('.main form').submit(function () {
$('button[type=submit]', this).attr('disabled', 'disabled');
});
});
})();
</script>

View File

@@ -155,8 +155,10 @@ $(document).ready(function() {
cid = idInput.val(),
draft = $('input[name=draft]'),
draftId = draft.length > 0 ? draft.val() : 0,
btnSave = $('#btn-save'),
btnSave = $('#btn-save').removeAttr('name').removeAttr('value'),
btnSubmit = $('#btn-submit').removeAttr('name').removeAttr('value'),
btnPreview = $('#btn-preview'),
doAction = $('<input type="hidden" name="do" value="publish" />').appendTo(form),
locked = false,
changed = false,
autoSave = $('<span id="auto-save-message" class="left"></span>').prependTo('.submit'),
@@ -199,7 +201,7 @@ $(document).ready(function() {
btnPreview.attr('disabled', 'disabled');
autoSave.text('<?php _e('正在保存'); ?>');
if (FormData !== undefined) {
if (typeof FormData !== 'undefined') {
var data = new FormData(form.get(0));
data.append('do', 'save');
@@ -328,6 +330,14 @@ $(document).ready(function() {
}
});
btnSave.click(function () {
doAction.attr('value', 'save');
});
btnSubmit.click(function () {
doAction.attr('value', 'publish');
});
// 控制选项和附件的切换
var fileUploadInit = false;
$('#edit-secondary .typecho-option-tabs li').click(function() {

View File

@@ -25,7 +25,7 @@ CREATE TABLE `typecho_comments` (
`authorId` int(10) unsigned default '0',
`ownerId` int(10) unsigned default '0',
`mail` varchar(150) default NULL,
`url` varchar(150) default NULL,
`url` varchar(255) default NULL,
`ip` varchar(64) default NULL,
`agent` varchar(511) default NULL,
`text` text,

View File

@@ -10,7 +10,7 @@ CREATE TABLE "typecho_comments" ( "coid" INT NOT NULL DEFAULT nextval('typecho_
"authorId" INT NULL DEFAULT '0',
"ownerId" INT NULL DEFAULT '0',
"mail" VARCHAR(150) NULL DEFAULT NULL,
"url" VARCHAR(150) NULL DEFAULT NULL,
"url" VARCHAR(255) NULL DEFAULT NULL,
"ip" VARCHAR(64) NULL DEFAULT NULL,
"agent" VARCHAR(511) NULL DEFAULT NULL,
"text" TEXT NULL DEFAULT NULL,

View File

@@ -5,7 +5,7 @@ CREATE TABLE typecho_comments ( "coid" INTEGER NOT NULL PRIMARY KEY,
"authorId" int(10) default '0' ,
"ownerId" int(10) default '0' ,
"mail" varchar(150) default NULL ,
"url" varchar(150) default NULL ,
"url" varchar(255) default NULL ,
"ip" varchar(64) default NULL ,
"agent" varchar(511) default NULL ,
"text" text ,

View File

@@ -22,7 +22,7 @@ define('__TYPECHO_MB_SUPPORTED__', function_exists('mb_get_info') && function_ex
class Typecho_Common
{
/** 程序版本 */
const VERSION = '1.1/17.12.14';
const VERSION = '1.2/18.1.29';
/**
* 允许的属性

View File

@@ -326,13 +326,24 @@ class Typecho_Db
return $this->sql()->insert($table);
}
/**
* @param $table
* @throws Typecho_Db_Exception
*/
public function truncate($table)
{
$table = preg_replace("/^table\./", $this->_prefix, $table);
$this->_adapter->truncate($table, $this->selectDb(self::WRITE));
}
/**
* 执行查询语句
*
* @param mixed $query 查询语句或者查询对象
* @param boolean $op 数据库读写状态
* @param int $op 数据库读写状态
* @param string $action 操作动作
* @return mixed
* @throws Typecho_Db_Exception
*/
public function query($query, $op = self::READ, $action = self::SELECT)
{

View File

@@ -39,6 +39,15 @@ interface Typecho_Db_Adapter
*/
public function getVersion($handle);
/**
* 清空数据表
*
* @param string $table 数据表名
* @param mixed $handle 连接对象
* @return mixed
*/
public function truncate($table, $handle);
/**
* 执行数据库查询
*

View File

@@ -65,7 +65,20 @@ class Typecho_Db_Adapter_Mysql implements Typecho_Db_Adapter
*/
public function getVersion($handle)
{
return 'ext:mysql ' . mysql_get_server_info($handle);
return 'mysql:mysql ' . mysql_get_server_info($handle);
}
/**
* 清空数据表
*
* @param string $table
* @param mixed $handle 连接对象
* @return mixed|void
* @throws Typecho_Db_Exception
*/
public function truncate($table, $handle)
{
$this->query('TRUNCATE TABLE ' . $this->quoteColumn($table), $handle);
}
/**

View File

@@ -63,7 +63,20 @@ class Typecho_Db_Adapter_Mysqli implements Typecho_Db_Adapter
*/
public function getVersion($handle)
{
return 'ext:mysqli ' . $this->_dbLink->server_version;
return 'mysqli:mysql ' . $this->_dbLink->server_version;
}
/**
* 清空数据表
*
* @param string $table
* @param mixed $handle 连接对象
* @return mixed|void
* @throws Typecho_Db_Exception
*/
public function truncate($table, $handle)
{
$this->query('TRUNCATE TABLE ' . $this->quoteColumn($table), $handle);
}
/**

View File

@@ -47,7 +47,7 @@ abstract class Typecho_Db_Adapter_Pdo implements Typecho_Db_Adapter
*
* @param Typecho_Config $config 数据库配置
* @throws Typecho_Db_Exception
* @return resource
* @return PDO
*/
public function connect(Typecho_Config $config)
{

View File

@@ -26,6 +26,19 @@ class Typecho_Db_Adapter_Pdo_Mysql extends Typecho_Db_Adapter_Pdo
return parent::isAvailable() && in_array('mysql', PDO::getAvailableDrivers());
}
/**
* 清空数据表
*
* @param string $table
* @param mixed $handle 连接对象
* @return mixed|void
* @throws Typecho_Db_Exception
*/
public function truncate($table, $handle)
{
$this->query('TRUNCATE TABLE ' . $this->quoteColumn($table), $handle);
}
/**
* 初始化数据库
*

View File

@@ -15,6 +15,20 @@ if (!defined('__TYPECHO_ROOT_DIR__')) exit;
*/
class Typecho_Db_Adapter_Pdo_Pgsql extends Typecho_Db_Adapter_Pdo
{
/**
* 主键列表
*
* @var array
*/
private $_pk = array();
/**
* 兼容的插入模式
*
* @var bool
*/
private $_compatibleInsert = false;
/**
* 判断适配器是否可用
*
@@ -26,6 +40,19 @@ class Typecho_Db_Adapter_Pdo_Pgsql extends Typecho_Db_Adapter_Pdo
return parent::isAvailable() && in_array('pgsql', PDO::getAvailableDrivers());
}
/**
* 清空数据表
*
* @param string $table
* @param mixed $handle 连接对象
* @return mixed|void
* @throws Typecho_Db_Exception
*/
public function truncate($table, $handle)
{
$this->query('TRUNCATE TABLE ' . $this->quoteColumn($table) . ' RESTART IDENTITY', $handle);
}
/**
* 初始化数据库
*
@@ -40,6 +67,51 @@ class Typecho_Db_Adapter_Pdo_Pgsql extends Typecho_Db_Adapter_Pdo
return $pdo;
}
/**
* 覆盖标准动作
* fix #710
*
* @param string $query
* @param mixed $handle
* @param int $op
* @param null $action
* @param null $table
* @return resource
* @throws Typecho_Db_Exception
*/
public function query($query, $handle, $op = Typecho_Db::READ, $action = NULL, $table = NULL)
{
if (Typecho_Db::INSERT == $action && !empty($table)) {
if (!isset($this->_pk[$table])) {
$result = $handle->query("SELECT
pg_attribute.attname,
format_type(pg_attribute.atttypid, pg_attribute.atttypmod)
FROM pg_index, pg_class, pg_attribute, pg_namespace
WHERE
pg_class.oid = " . $this->quoteValue($table) . "::regclass AND
indrelid = pg_class.oid AND
nspname = 'public' AND
pg_class.relnamespace = pg_namespace.oid AND
pg_attribute.attrelid = pg_class.oid AND
pg_attribute.attnum = any(pg_index.indkey)
AND indisprimary")->fetch(PDO::FETCH_ASSOC);
if (!empty($result)) {
$this->_pk[$table] = $result['attname'];
}
}
// 使用兼容模式监听插入结果
if (isset($this->_pk[$table])) {
$this->_compatibleInsert = true;
$query .= ' RETURNING ' . $this->quoteColumn($this->_pk[$table]);
}
}
return parent::query($query, $handle, $op, $action, $table); // TODO: Change the autogenerated stub
}
/**
* 对象引号过滤
*
@@ -84,8 +156,11 @@ class Typecho_Db_Adapter_Pdo_Pgsql extends Typecho_Db_Adapter_Pdo
*/
public function lastInsertId($resource, $handle)
{
/** 查看是否存在序列,可能需要更严格的检查 */
if ($handle->query('SELECT oid FROM pg_class WHERE relname = ' . $this->quoteValue($this->_lastTable . '_seq'))->fetchAll()) {
if ($this->_compatibleInsert) {
$this->_compatibleInsert = false;
return $resource->fetchColumn(0);
} else if ($handle->query('SELECT oid FROM pg_class WHERE relname = ' . $this->quoteValue($this->_lastTable . '_seq'))->fetchAll()) {
/** 查看是否存在序列,可能需要更严格的检查 */
return $handle->lastInsertId($this->_lastTable . '_seq');
}

View File

@@ -31,6 +31,19 @@ class Typecho_Db_Adapter_Pdo_SQLite extends Typecho_Db_Adapter_Pdo
return parent::isAvailable() && in_array('sqlite', PDO::getAvailableDrivers());
}
/**
* 清空数据表
*
* @param string $table
* @param mixed $handle 连接对象
* @return mixed|void
* @throws Typecho_Db_Exception
*/
public function truncate($table, $handle)
{
$this->query('DELETE FROM ' . $this->quoteColumn($table), $handle);
}
/**
* 初始化数据库
*

View File

@@ -71,7 +71,20 @@ class Typecho_Db_Adapter_Pgsql implements Typecho_Db_Adapter
public function getVersion($handle)
{
$version = pg_version($handle);
return 'ext:pgsql ' . $version['server'];
return 'pgsql:pgsql ' . $version['server'];
}
/**
* 清空数据表
*
* @param string $table
* @param mixed $handle 连接对象
* @return mixed|void
* @throws Typecho_Db_Exception
*/
public function truncate($table, $handle)
{
$this->query('TRUNCATE TABLE ' . $this->quoteColumn($table) . ' RESTART IDENTITY', $handle);
}
/**

View File

@@ -59,7 +59,20 @@ class Typecho_Db_Adapter_SQLite implements Typecho_Db_Adapter
*/
public function getVersion($handle)
{
return 'ext:sqlite ' . sqlite_libversion();
return 'sqlite:sqlite ' . sqlite_libversion();
}
/**
* 清空数据表
*
* @param string $table
* @param mixed $handle 连接对象
* @return mixed|void
* @throws Typecho_Db_Exception
*/
public function truncate($table, $handle)
{
$this->query('DELETE FROM ' . $this->quoteColumn($table), $handle);
}
/**

View File

@@ -1316,6 +1316,70 @@ Typecho_Date::setTimezoneOffset($options->timezone);
"text" text ,
"type" varchar(16) default \'comment\' ,
"status" varchar(16) default \'approved\' ,
"parent" int(10) default \'0\')', Typecho_Db::WRITE);
$db->query('INSERT INTO ' . $prefix . 'comments SELECT * FROM ' . $prefix . 'comments' . $uuid, Typecho_Db::WRITE);
$db->query('DROP TABLE ' . $prefix . 'comments' . $uuid, Typecho_Db::WRITE);
$db->query('CREATE INDEX ' . $prefix . 'comments_cid ON ' . $prefix . 'comments ("cid")', Typecho_Db::WRITE);
$db->query('CREATE INDEX ' . $prefix . 'comments_created ON ' . $prefix . 'comments ("created")', Typecho_Db::WRITE);
$db->flushPool();
break;
default:
break;
}
}
/**
* 升级至18.1.29
*
* @param $db
*/
public static function v1_2r18_1_29($db)
{
/** 修改数据库字段 */
$adapterName = $db->getAdapterName();
$prefix = $db->getPrefix();
switch (true) {
case false !== strpos($adapterName, 'Mysql'):
$db->query("ALTER TABLE `" . $prefix . "comments` MODIFY COLUMN `url` varchar(255)", Typecho_Db::WRITE);
break;
case false !== strpos($adapterName, 'Pgsql'):
$db->query('ALTER TABLE "' . $prefix . 'comments" ALTER COLUMN "url" TYPE varchar(255)', Typecho_Db::WRITE);
break;
case false !== strpos($adapterName, 'SQLite'):
$uuid = uniqid();
$db->query('CREATE TABLE ' . $prefix . 'comments' . $uuid . ' ( "coid" INTEGER NOT NULL PRIMARY KEY,
"cid" int(10) default \'0\' ,
"created" int(10) default \'0\' ,
"author" varchar(150) default NULL ,
"authorId" int(10) default \'0\' ,
"ownerId" int(10) default \'0\' ,
"mail" varchar(150) default NULL ,
"url" varchar(255) default NULL ,
"ip" varchar(64) default NULL ,
"agent" varchar(511) default NULL ,
"text" text ,
"type" varchar(16) default \'comment\' ,
"status" varchar(16) default \'approved\' ,
"parent" int(10) default \'0\')', Typecho_Db::WRITE);
$db->query('INSERT INTO ' . $prefix . 'comments' . $uuid . ' SELECT * FROM ' . $prefix . 'comments', Typecho_Db::WRITE);
$db->query('DROP TABLE ' . $prefix . 'metas', Typecho_Db::WRITE);
$db->query('CREATE TABLE ' . $prefix . 'comments ( "coid" INTEGER NOT NULL PRIMARY KEY,
"cid" int(10) default \'0\' ,
"created" int(10) default \'0\' ,
"author" varchar(150) default NULL ,
"authorId" int(10) default \'0\' ,
"ownerId" int(10) default \'0\' ,
"mail" varchar(150) default NULL ,
"url" varchar(255) default NULL ,
"ip" varchar(64) default NULL ,
"agent" varchar(511) default NULL ,
"text" text ,
"type" varchar(16) default \'comment\' ,
"status" varchar(16) default \'approved\' ,
"parent" int(10) default \'0\')', Typecho_Db::WRITE);
$db->query('INSERT INTO ' . $prefix . 'comments SELECT * FROM ' . $prefix . 'comments' . $uuid, Typecho_Db::WRITE);
$db->query('DROP TABLE ' . $prefix . 'comments' . $uuid, Typecho_Db::WRITE);

View File

@@ -28,6 +28,9 @@ class Widget_Backup extends Widget_Abstract_Options implements Widget_Interface_
'fields' => 6
);
/**
* @var array
*/
private $_fields = array(
'contents' => array(
'cid', 'title', 'slug', 'created', 'modified', 'text', 'order', 'authorId',
@@ -49,6 +52,11 @@ class Widget_Backup extends Widget_Abstract_Options implements Widget_Interface_
)
);
/**
* @var array
*/
private $_lastIds = array();
/**
* @var array
*/
@@ -71,8 +79,15 @@ class Widget_Backup extends Widget_Abstract_Options implements Widget_Interface_
$result = array();
foreach ($data as $key => $val) {
if (in_array($key, $this->_fields[$table])) {
$index = array_search($key, $this->_fields[$table]);
if ($index !== false) {
$result[$key] = $val;
if ($index === 0 && !in_array($table, array('relationships', 'fields'))) {
$this->_lastIds[$table] = isset($this->_lastIds[$table])
? max($this->_lastIds[$table], $val) : $val;
}
}
}
@@ -154,6 +169,14 @@ class Widget_Backup extends Widget_Abstract_Options implements Widget_Interface_
$this->processData($type, $header, $body);
}
// 针对PGSQL重置计数
if (false !== strpos($this->db->getVersion(), 'pgsql')) {
foreach ($this->_lastIds as $table => $id) {
$seq = $this->db->getPrefix() . $table . '_seq';
$this->db->query('ALTER SEQUENCE ' . $seq . ' RESTART WITH ' . ($id + 1));
}
}
@fclose($fp);
$this->widget('Widget_Notice')->set(_t('数据恢复完成'), 'success');
$this->response->goBack();
@@ -189,6 +212,7 @@ class Widget_Backup extends Widget_Abstract_Options implements Widget_Interface_
*
* @param $table
* @param $data
* @throws Typecho_Exception
*/
private function importData($table, $data)
{
@@ -197,7 +221,7 @@ class Widget_Backup extends Widget_Abstract_Options implements Widget_Interface_
try {
if (empty($this->_cleared[$table])) {
// 清除数据
$db->query($db->delete('table.' . $table));
$db->truncate('table.' . $table);
$this->_cleared[$table] = true;
}

View File

@@ -79,7 +79,7 @@ class Widget_Feedback extends Widget_Abstract_Comments implements Widget_Interfa
$validator->addRule('url', 'required', _t('必须填写个人主页'));
}
$validator->addRule('url', 'url', _t('个人主页地址格式错误'));
$validator->addRule('url', 'maxLength', _t('个人主页地址最多包含150个字符'), 150);
$validator->addRule('url', 'maxLength', _t('个人主页地址最多包含255个字符'), 255);
$validator->addRule('text', 'required', _t('必须填写评论内容'));
@@ -186,7 +186,7 @@ class Widget_Feedback extends Widget_Abstract_Comments implements Widget_Interfa
$validator = new Typecho_Validate();
$validator->addRule('url', 'required', 'We require all Trackbacks to provide an url.')
->addRule('url', 'url', 'Your url is not valid.')
->addRule('url', 'maxLength', 'Your url is not valid.', 150)
->addRule('url', 'maxLength', 'Your url is not valid.', 255)
->addRule('text', 'required', 'We require all Trackbacks to provide an excerption.')
->addRule('author', 'required', 'We require all Trackbacks to provide an blog name.')
->addRule('author', 'xssCheck', 'Your blog name is not valid.')