Files

386 lines
12 KiB
PHP
Raw Permalink Normal View History

2026-02-23 17:23:48 +08:00
<?php
class DevelopmentHistory_Action
{
/**
* 数据库对象
*/
private $db;
private $prefix;
/**
* 请求对象
*/
private $request;
/**
* 响应对象
*/
private $response;
/**
* 构造函数
*/
public function __construct($request = null, $response = null)
{
$this->db = Typecho_Db::get();
$this->prefix = $this->db->getPrefix();
$this->request = $request ?: Typecho_Request::getInstance();
$this->response = $response ?: Typecho_Response::getInstance();
}
/**
* 添加历史记录 - 修复使用Typecho正确的SQL构建方法
*/
public function addHistory($data)
{
try {
$now = new Typecho_Date(Typecho_Date::gmtTime());
$insert = array(
'content' => $data['content'],
'event_date' => $data['event_date'],
'post_cids' => isset($data['post_cids']) ? $this->cleanCids($data['post_cids']) : '',
'created' => $now->format('Y-m-d H:i:s'),
'modified' => $now->format('Y-m-d H:i:s'),
'status' => 1
);
// 使用Typecho的查询构建器但先验证数据
$this->validateInsertData($insert);
// 修复:正确构建并执行插入查询
// 在Typecho中insert()->rows()需要调用query()方法来执行
$query = $this->db->insert($this->prefix . 'development_history')->rows($insert);
// 执行查询
$this->db->query($query);
// 获取最后插入的ID - Typecho的方式
$row = $this->db->fetchRow($this->db->select('LAST_INSERT_ID() as id'));
return $row ? $row['id'] : 0;
} catch (Exception $e) {
error_log("addHistory Error: " . $e->getMessage());
error_log("Data: " . print_r($data, true));
throw new Exception("发布失败: " . $e->getMessage());
}
}
/**
* 验证插入数据
*/
private function validateInsertData(&$data)
{
// 确保所有必需字段都有值
if (empty($data['content'])) {
throw new Exception("内容不能为空");
}
if (empty($data['event_date'])) {
throw new Exception("日期不能为空");
}
// 验证日期格式
if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $data['event_date'])) {
throw new Exception("日期格式错误应为YYYY-MM-DD");
}
// 清理和转义内容
$data['content'] = trim($data['content']);
if (empty($data['content'])) {
throw new Exception("内容不能为空");
}
// 确保所有字段都是字符串
foreach ($data as $key => $value) {
if (!is_string($value) && !is_numeric($value)) {
$data[$key] = (string)$value;
}
}
}
/**
* 批量添加历史记录按事件时间排序插入越近的ID越大
*/
public function batchAddHistories($histories)
{
// 按事件时间排序越近的时间越晚插入这样ID越大
usort($histories, function($a, $b) {
return strtotime($a['event_date']) - strtotime($b['event_date']);
});
$now = new Typecho_Date(Typecho_Date::gmtTime());
$nowStr = $now->format('Y-m-d H:i:s');
foreach ($histories as $history) {
$insert = array(
'content' => $history['content'],
'event_date' => $history['event_date'],
'post_cids' => '',
'created' => $nowStr,
'modified' => $nowStr,
'status' => 1
);
$query = $this->db->insert($this->prefix . 'development_history')->rows($insert);
$this->db->query($query);
}
}
/**
* 更新历史记录
*/
public function updateHistory($data)
{
try {
$now = new Typecho_Date(Typecho_Date::gmtTime());
$update = array(
'content' => $data['edit_content'],
'event_date' => $data['edit_event_date'],
'post_cids' => isset($data['edit_post_cids']) ? $this->cleanCids($data['edit_post_cids']) : '',
'modified' => $now->format('Y-m-d H:i:s')
);
$query = $this->db->update($this->prefix . 'development_history')
->rows($update)
->where('id = ?', intval($data['edit_id']));
$this->db->query($query);
} catch (Exception $e) {
error_log("updateHistory Error: " . $e->getMessage());
throw new Exception("更新失败: " . $e->getMessage());
}
}
/**
* 删除历史记录
*/
public function deleteHistory($id)
{
$query = $this->db->delete($this->prefix . 'development_history')->where('id = ?', intval($id));
$this->db->query($query);
}
/**
* 批量删除
*/
public function deleteHistories($ids)
{
foreach ($ids as $id) {
$this->deleteHistory(intval($id));
}
}
/**
* 获取历史记录
*/
public function getHistories($page = 1, $perPage = 10)
{
$offset = ($page - 1) * $perPage;
$query = $this->db->select()
->from($this->prefix . 'development_history')
->where('status = ?', 1)
->order('id', Typecho_Db::SORT_DESC)
->limit($perPage)
->offset($offset);
return $this->db->fetchAll($query);
}
/**
* 获取所有历史记录(用于导出)
*/
public function getAllHistories()
{
$query = $this->db->select()
->from($this->prefix . 'development_history')
->where('status = ?', 1)
->order('id', Typecho_Db::SORT_DESC);
return $this->db->fetchAll($query);
}
/**
* 获取总记录数
*/
public function getTotalCount()
{
$query = $this->db->select('COUNT(*) as count')
->from($this->prefix . 'development_history')
->where('status = ?', 1);
$result = $this->db->fetchRow($query);
return $result['count'];
}
/**
* 获取单条记录
*/
public function getHistory($id)
{
$query = $this->db->select()
->from($this->prefix . 'development_history')
->where('id = ?', $id)
->limit(1);
return $this->db->fetchRow($query);
}
/**
* 根据文章CID获取文章信息
*/
public function getPostByCid($cid)
{
try {
$query = $this->db->select('cid, title, slug, created')
->from($this->prefix . 'contents')
->where('cid = ?', intval($cid))
->where('type = ?', 'post')
->where('status = ?', 'publish')
->limit(1);
$post = $this->db->fetchRow($query);
if ($post) {
$options = Typecho_Widget::widget('Widget_Options');
if (!empty($post['slug'])) {
$post['url'] = Typecho_Common::url($post['slug'] . '.html', $options->index);
} else {
$post['url'] = Typecho_Common::url('archives/' . $post['cid'], $options->index);
}
}
return $post;
} catch (Exception $e) {
return null;
}
}
/**
* 清理CID字符串
*/
private function cleanCids($cids)
{
if (empty($cids)) {
return '';
}
$cidsArray = array_filter(array_map('trim', explode(',', $cids)));
$validCids = array();
foreach ($cidsArray as $cid) {
if (is_numeric($cid) && $cid > 0) {
$validCids[] = intval($cid);
}
}
// 去重并返回逗号分隔的字符串
return implode(',', array_unique($validCids));
}
/**
* 导出数据为文本格式
*/
public function exportData()
{
$histories = $this->getAllHistories();
$content = '';
foreach ($histories as $history) {
// 使用 Y.m.d 格式导出
$date = date('Y.m.d', strtotime($history['event_date']));
$text = str_replace(array("\r\n", "\r", "\n"), " ", $history['content']);
$content .= $date . ' ' . $text . "\n";
}
return $content;
}
/**
* 导入数据(增强版,支持调试)
*/
public function importData($text)
{
// 标准化换行符
$text = str_replace("\r\n", "\n", $text);
$text = str_replace("\r", "\n", $text);
$lines = explode("\n", $text);
$imported = 0;
$failed = 0;
$failReasons = array(); // 记录失败原因
$histories = array();
foreach ($lines as $lineNum => $line) {
$line = trim($line);
if (empty($line)) continue;
// 移除行尾的分号(如果有)
if (substr($line, -1) === ';') {
$line = substr($line, 0, -1);
$line = trim($line);
}
// 找到第一个空格的位置来分割日期和内容
$firstSpacePos = strpos($line, ' ');
if ($firstSpacePos === false) {
$failed++;
$failReasons[] = "" . ($lineNum + 1) . " 行:找不到空格分隔日期和内容 - '{$line}'";
continue;
}
$date = trim(substr($line, 0, $firstSpacePos));
$content = trim(substr($line, $firstSpacePos + 1));
// 验证日期格式 - 支持单个数字的月份和日期
// 允许的格式YYYY.M.D, YYYY.MM.D, YYYY.M.DD, YYYY.MM.DD
$datePattern = '/^(\d{4})\.(\d{1,2})\.(\d{1,2})$/';
if (!preg_match($datePattern, $date, $matches)) {
$failed++;
$failReasons[] = "" . ($lineNum + 1) . " 行:日期格式错误,应为 YYYY.M[M].D[D] - '{$date}'";
continue;
}
// 检查日期是否有效
$year = intval($matches[1]);
$month = intval($matches[2]);
$day = intval($matches[3]);
if (!checkdate($month, $day, $year)) {
$failed++;
$failReasons[] = "" . ($lineNum + 1) . " 行:无效的日期 - {$date}";
continue;
}
// 转换日期格式为 Y-m-d 以便数据库存储,补零成两位数字
$dbDate = sprintf('%04d-%02d-%02d', $year, $month, $day);
// 验证内容
if (empty($content)) {
$failed++;
$failReasons[] = "" . ($lineNum + 1) . " 行:内容为空";
continue;
}
$histories[] = array(
'event_date' => $dbDate,
'content' => $content
);
$imported++;
}
if (!empty($histories)) {
$this->batchAddHistories($histories);
}
// 返回包含失败原因的结果
return array(
'imported' => $imported,
'failed' => $failed,
'fail_reasons' => $failReasons
);
}
}