浏览 2925 次 / [ 天下网闻 ] DISCUZ修改重建封面变成系统默认封面BUG解决方法
  • 发布时间 2018-01-24 20:30
  • 有图片展示版的站长可能发现,在重新封面的时候,封面已经不是自己选择的图了,而是发帖时系统默认的了。这个问题反馈了半年了,人家不当是问题。所以就这样了。自己动手吧。(其实有时真不是自己不会修改,也不是自己不想去修改,只是自己修改的太多,影响升级。但人家死活不重视,你拿他没有办法。)
    需要修改的文件
    source/admincp/admincp_counter.php
    source/function/function_post.php
    source/class/table/table_forum_threadimage.php

    老规距,先分析问题。

    为什么会这样,其实原因很简单,在重建的时候,没有读取自己设置的封面,而只是直接从主题附件里面选择最后上传的那张图片。

    首先,看看数据库

    SELECT *
    FROM `pre_forum_threadimage`
    LIMIT 0 , 30
            tid        attachment        remote
            编辑        删除        1        201309/23/171902q7ahfsbt7xz957t7.jpg        0
            编辑        删除        2        201310/30/114312uw221w8t8vw1z1yj.jpg        0
            编辑        删除        3        201310/30/114537rlgk0k2kli2z9xg1.jpg        0
            编辑        删除        4        201310/30/114619sutk8vvhunxvdbpk.jpg        0
            编辑        删除        5        201310/30/114859ylvwz196kdmgw19q.jpg        0
            编辑        删除        6        201310/30/120641lgkgq1oa7x00anag.jpg        0
            编辑        删除        7        201310/30/121726olrzq3qkpnw383tz.jpg        0
            编辑        删除        9        201310/30/122003uk63etg6wmtjjh4e.jpg        0
            编辑        删除        11        201310/30/141256ixgxc0m0xzhqg0g0.jpg        0
            编辑        删除        12        201310/30/141344qtaide36tzdilz35.jpg        0
            编辑        删除        14        201312/29/225508mr9f7rdt7dhbbkp9.jpg        0

    我们看到,数据库记录了封面图片的原文件。
    有原文件记录就好办了,再看看文件吧,打开
    source/admincp/admincp_counter.php
    关键部位 451-456行,版本不同略有不同

    foreach(C::t('forum_thread')->fetch_all_by_fid_cover_lastpost($fid, $cover, $starttime, $endtime, $current, $pertask) as $thread) {
                    $processed = 1;
                    $pid = C::t('forum_post')->fetch_threadpost_by_tid_invisible($thread['tid'], 0);
                    $pid = $pid['pid'];
                    setthreadcover($pid);
                    setthreadcover($pid,$thread['tid']);
            }

    可以很明显的看到,数据库中只记录了TID,而处理函数是处理PID(红色字体)
    因此我们需要修改如下:
    1. foreach(C::t('forum_thread')->fetch_all_by_fid_cover_lastpost($fid, $cover, $starttime, $endtime, $current, $pertask) as $thread) {
    2.                 $processed = 1;
    3.                 $pid = C::t('forum_post')->fetch_threadpost_by_tid_invisible($thread['tid'], 0);
    4.                 $pid = $pid['pid'];
    5.                 setthreadcover($pid,$thread['tid']);
    6.         }
    复制代码
    好,现在我们找到setthreadcover函数。
    在source/function/function_post.php文件的最后
    1. function setthreadcover($pid, $tid = 0, $aid = 0, $countimg = 0, $imgurl = '') {
    2.         global $_G;
    3.         $cover = 0;
    4.         if(empty($_G['uid']) || !intval($_G['setting']['forumpicstyle']['thumbheight']) || !intval($_G['setting']['forumpicstyle']['thumbwidth'])) {
    5.                 return false;
    6.         }

    7.         if(($pid || $aid) && empty($countimg)) {
    8.                 if(empty($imgurl)) {
    9.                         if($aid) {
    10.                                 $attachtable = 'aid:'.$aid;
    11.                                 $attach = C::t('forum_attachment_n')->fetch('aid:'.$aid, $aid, array(1, -1));
    12.                         }else{
    13.                                 $attachtable = 'pid:'.$pid;
    14.                                 $attach = C::t('forum_attachment_n')->fetch_max_image('pid:'.$pid, 'pid', $pid);
    15.                                 
    16.                         }
    17.                         if(!$attach) {
    18.                                 return false;
    19.                         }
    20.                         if(empty($_G['forum']['ismoderator']) && $_G['uid'] != $attach['uid']) {
    21.                                 return false;
    22.                         }
    23.                         $pid = empty($pid) ? $attach['pid'] : $pid;
    24.                         $tid = empty($tid) ? $attach['tid'] : $tid;
    25.                         $picsource = ($attach['remote'] ? $_G['setting']['ftp']['attachurl'] : $_G['setting']['attachurl']).'forum/'.$attach['attachment'];
    26.                 } else {
    27.                         $attachtable = 'pid:'.$pid;
    28.                         $picsource = $imgurl;
    29.                 }

    30.                 $basedir = !$_G['setting']['attachdir'] ? (DISCUZ_ROOT.'./data/attachment/') : $_G['setting']['attachdir'];
    31.                 $coverdir = 'threadcover/'.substr(md5($tid), 0, 2).'/'.substr(md5($tid), 2, 2).'/';
    32.                 dmkdir($basedir.'./forum/'.$coverdir);

    33.                 require_once libfile('class/image');
    34.                 $image = new image();
    35.                 if($image->Thumb($picsource, 'forum/'.$coverdir.$tid.'.jpg', $_G['setting']['forumpicstyle']['thumbwidth'], $_G['setting']['forumpicstyle']['thumbheight'], 2)) {
    36.                         $remote = '';
    37.                         if(getglobal('setting/ftp/on')) {
    38.                                 if(ftpcmd('upload', 'forum/'.$coverdir.$tid.'.jpg')) {
    39.                                         $remote = '-';
    40.                                 }
    41.                         }
    42.                         $cover = C::t('forum_attachment_n')->count_image_by_id($attachtable, 'pid', $pid);
    43.                         if($imgurl && empty($cover)) {
    44.                                 $cover = 1;
    45.                         }
    46.                         $cover = $remote.$cover;
    47.                 } else {
    48.                         return false;
    49.                 }
    50.         }
    51.         if($countimg) {
    52.                 if(empty($cover)) {
    53.                         $thread = C::t('forum_thread')->fetch($tid);
    54.                         $oldcover = $thread['cover'];

    55.                         $cover = C::t('forum_attachment_n')->count_image_by_id('tid:'.$tid, 'pid', $pid);
    56.                         if($cover) {
    57.                                 $cover = $oldcover < 0 ? '-'.$cover : $cover;
    58.                         }
    59.                 }
    60.         }
    61.         if($cover) {
    62.                 C::t('forum_thread')->update($tid, array('cover' => $cover));
    63.                 return true;
    64.         }
    65. }
    复制代码
    发现这个函数有传递TID的参数。但在读取图片数据的时候只处理了AID和PID的情况,并没有TID

    if(($pid || $aid) && empty($countimg)) {
                    if(empty($imgurl)) {
                            if($aid) {
                                    $attachtable = 'aid:'.$aid;
                                    $attach = C::t('forum_attachment_n')->fetch('aid:'.$aid, $aid, array(1, -1));
                            }else{
                                    $attachtable = 'pid:'.$pid;
                                    $attach = C::t('forum_attachment_n')->fetch_max_image('pid:'.$pid, 'pid', $pid);
                                    
                            }

    OK,那我们把他加上吧,修改如下:
    1. if(($pid || $aid) && empty($countimg)) {
    2.                 if(empty($imgurl)) {
    3.                         if($aid) {
    4.                                 $attachtable = 'aid:'.$aid;
    5.                                 $attach = C::t('forum_attachment_n')->fetch('aid:'.$aid, $aid, array(1, -1));
    6.                         } elseif($tid) {
    7.                                 $attachtable = 'pid:'.$pid;
    8.                                 $attach = C::t('forum_threadimage')->fetch($tid);
    9.                         }else{
    10.                                 $attachtable = 'pid:'.$pid;
    11.                                 $attach = C::t('forum_attachment_n')->fetch_max_image('pid:'.$pid, 'pid', $pid);
    12.                                 
    13.                         }
    复制代码
    在上面的代码修改中,我们给forum_threadimage添加了fetch动作。
    因此,需要打开source/class/table/table_forum_threadimage.php 文件给他添加fetch动作
    1. public function fetch($tid) {
    2.                 return DB::fetch_first('SELECT * FROM %t WHERE tid=%d', array($this->_table,$tid));
    3.         }
    复制代码
    到些全部修改完毕,测试通过。希望有一定基础的站长,测试一下,有没有其它方面的问题。



    本文转自:http://www.discuz.net/thread-3499604-1-1.html    感谢作者fareign提供的解决方法:)
    [作者发布于2013年,经本站测试DISCUZ X3.4版本有效,另外很重要的是对应之前批量生成已经被替换为系统默认封面的,本方法执行后可自动恢复为当时手动设置的封面]
    以下为修改后的三个文件,注意备份,仅   供   参   考

    (11.28 KB) (无法下载?提醒修复 )




    2018.10.24补充个建议:
    重新生成封面前,将附件目录里的forum/threadcover打包备份,threadcoer里是所有帖子的封面,如果重新生成出了问题,也好再覆盖回去,
    毕竟重生前后的封面图片名称和路径是相同的。