【思路解析】discuz 帖子设置封面 setthreadcover 表pre_forum_threadimage

在Discuz 中有一项就是给帖子设置封面,很多情况下只能通过手动的方式去设置或者用提交POST请求的式去设置; 但是这都是调用DISCUZ的功能设置的; 有的时候并非万能的,也有用不到的时候;下面就给大家讲一下DISCUZ在设计封面的设计思路; 知道了思路,就可以自己用代码去实现;

好开始:

在设置了封面后,会在 pre_forum_threadimage 中插入一条这样的数据;

tid 是贴子的ID  后面的是对应的附件的地址;

在点击设置封面的时候会看到,程序会请求一个地址如下图

对是他:

http://localhost/dz/forum.php?mod=ajax&action=setthreadcover&aid=1&fid=36&infloat=yes&handlekey=setcover1&inajax=1&ajaxtarget=fwin_content_setcover1

在这个请求的连接中对我们重要的有  mod /action/fid/aid这几个参数; 请求的是Forum.php 那我们去找。

在Forum.php的最后,我们发现了下面一句代码:

require DISCUZ_ROOT.'./source/module/forum/forum_'.$mod.'.php';

根据这句代码和请求参数,我们找到了:source/module/forum/forum_ajax.php 这个文件,并在里面找到了setthreadcover的处理代码如下:

elseif($_GET['action'] == 'setthreadcover') {
	$aid = intval($_GET['aid']);
	$imgurl = $_GET['imgurl'];
	require_once libfile('function/post');
	if($_G['forum'] && ($aid || $imgurl)) {
		if($imgurl) {
			$tid = intval($_GET['tid']);
			$pid = intval($_GET['pid']);
		} else {
			$threadimage = C::t('forum_attachment_n')->fetch('aid:'.$aid, $aid);
			$tid = $threadimage['tid'];
			$pid = $threadimage['pid'];
		}

		if($tid && $pid) {
			$thread =get_thread_by_tid($tid);
		} else {
			$thread = array();
		}
		if(empty($thread) || (!$_G['forum']['ismoderator'] && $_G['uid'] != $thread['authorid'])) {
			if($_GET['newthread']) {
				showmessage('set_cover_faild', '', array(), array('msgtype' => 3));
			} else {
				showmessage('set_cover_faild', '', array(), array('closetime' => 3));
			}
		}
		if(setthreadcover($pid, $tid, $aid, 0, $imgurl)) {
			if(empty($imgurl)) {
				C::t('forum_threadimage')->delete_by_tid($threadimage['tid']);
				C::t('forum_threadimage')->insert(array(
					'tid' => $threadimage['tid'],
					'attachment' => $threadimage['attachment'],
					'remote' => $threadimage['remote'],
				));
			}
			if($_GET['newthread']) {
				showmessage('set_cover_succeed', '', array(), array('msgtype' => 3));
			} else {
				showmessage('set_cover_succeed', '', array(), array('alert' => 'right', 'closetime' => 1));
			}
		}
	}
	if($_GET['newthread']) {
		showmessage('set_cover_faild', '', array(), array('msgtype' => 3));
	} else {
		showmessage('set_cover_faild', '', array(), array('closetime' => 3));
	}

} 

在这一段代码中,最重要的一段代码是:if(setthreadcover($pid, $tid, $aid, 0, $imgurl))   不用看下面的代码怎么处理的,但是我们可以猜到在调用过setthreadcover 这个函数之后,封面已经设置完成了;

那setthreadcover 这个函数到底在哪呢?我也找也半天,最后终于在:source/function/function_post.php  这个文件里找到了它,代码如下:

function setthreadcover($pid, $tid = 0, $aid = 0, $countimg = 0, $imgurl = '') {
	global $_G;
	$cover = 0;
	if(empty($_G['uid']) || !intval($_G['setting']['forumpicstyle']['thumbheight']) || !intval($_G['setting']['forumpicstyle']['thumbwidth'])) {
		return false;
	}

	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);
			}
			if(!$attach) {
				return false;
			}
			if(empty($_G['forum']['ismoderator']) && $_G['uid'] != $attach['uid']) {
				return false;
			}
			$pid = empty($pid) ? $attach['pid'] : $pid;
			$tid = empty($tid) ? $attach['tid'] : $tid;
			$picsource = ($attach['remote'] ? $_G['setting']['ftp']['attachurl'] : $_G['setting']['attachurl']).'forum/'.$attach['attachment'];
		} else {
			$attachtable = 'pid:'.$pid;
			$picsource = $imgurl;
		}

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

		require_once libfile('class/image');
		$image = new image();
		if($image->Thumb($picsource, 'forum/'.$coverdir.$tid.'.jpg', $_G['setting']['forumpicstyle']['thumbwidth'], $_G['setting']['forumpicstyle']['thumbheight'], 2)) {
			$remote = '';
			if(getglobal('setting/ftp/on')) {
				if(ftpcmd('upload', 'forum/'.$coverdir.$tid.'.jpg')) {
					$remote = '-';
				}
			}
			$cover = C::t('forum_attachment_n')->count_image_by_id($attachtable, 'pid', $pid);
			if($imgurl && empty($cover)) {
				$cover = 1;
			}
			$cover = $remote.$cover;
		} else {
			return false;
		}
	}
	if($countimg) {
		if(empty($cover)) {
			$thread = C::t('forum_thread')->fetch($tid);
			$oldcover = $thread['cover'];

			$cover = C::t('forum_attachment_n')->count_image_by_id('tid:'.$tid, 'pid', $pid);
			if($cover) {
				$cover = $oldcover < 0 ? '-'.$cover : $cover;
			}
		}
	}
	if($cover) {
		C::t('forum_thread')->update($tid, array('cover' => $cover));
		return true;
	}
}

整个这个函数就是处理设置封面的处理函数,处理过程不过多解释,只讲思路,在这个函数中有一句重要的代码是这样的:

if(ftpcmd('upload', 'forum/'.$coverdir.$tid.'.jpg')) {

在查看封面请求地址的时候,会感觉到封面缩略图存放的地址很怪异如下:

c4/ca? 看起来是随机的,与上面提到的封面数据库存储的完全不一样,到底是怎么样对应上的呢;

那我们还得看上面我们提到的函数 setthreadcover 了,上面我们说if(ftpcmd(‘upload‘, ‘forum/‘.$coverdir.$tid.‘.jpg‘)) { //这句代码很重要

ftpcmd 这个什么作用,看到后面的upload我们有理由猜到,这句代码是实现的是一个上传图片的操作; 那能在这个函数里面处理的,肯定是上传缩略图到新的路径了。

那路径在哪呢 ‘forum/‘.$coverdir.$tid.‘ //对就是后面这一句就是上传的路径。

$tid 不用说,那肯定是贴子的ID也就是这个封面图的文件名;至于 $coverdir 这个我们不难发现,这个就是路径,通过这个我们往上找;找到了这段代码:

$coverdir = 'threadcover/'.substr(md5($tid), 0, 2).'/'.substr(md5($tid), 2, 2).'/';

到此就真相大白了,他生成目录的方式是截取$tid MD5加密后的前两位作为一个目录和第三、四位做了一个目录;为了证明我们的猜测,做如下比较:

再看我们的目录:

完全稳合,知道了DISCUZ的设置思路,那我们就算以后自己给自己的论坛开接口的时候就可以用程序的试实现自动发贴并设置封面了。

总结:很明显DISCUZ使用了新建目录的方式用来存放贴子的封面,不知道他们为何会这么设计 ,感觉很蛋疼,个人认为完全没必要;

时间: 2024-08-04 01:15:07

【思路解析】discuz 帖子设置封面 setthreadcover 表pre_forum_threadimage的相关文章

[Ecmall]ECMALL目录结构设置与数据库表

最近在做ecmall的开发,ecmall在开源方面还有待进步啊,官方没有提供开发文档,也没有关于系统架构组织的贡献,使用者都要自己从0开始,官方论坛连二次开发板块都没有,都在哪瞎扯淡,广告一堆.可悲~~~ 自己做了一张图片,根据ecmall的程序结构图,可以清楚的知道ecmall的五脏六腑. ECMALL数据库主要表 ecm_acategory:存放的是商城的文章分类. ecm_address:存放的是店长的地址 ecm_article:存放的是商城的相关文章 ecm_brand:存放的是商城的

u-boot分析(四)---设置异常向量表|设置SVC模式

u-boot分析(四) 通过前三篇的分析,我们对u-boot已经有了整体的认识和掌握,但是我们仍然对于其部分硬件是如何初始化的不太清楚,所以接下来几篇博文我将会对我们在http://www.cnblogs.com/wrjvszq/archive/2015/01/10/4215627.html一文中总结出的u-boot的工作流程中的重要环节,结合文档加以分析. 今天我们会用到的文档: 1.        ARM Architecture Reference Manual:http://downlo

使用SQL命令手动写入Discuz帖子内容

-- 转存表中的数据`forum_post` INSERT INTO `forum_post` (`pid`, `fid`,`tid`, `first`, `author`, `authorid`, `subject`, `dateline`, `message`,`useip`, `invisible`, `anonymous`, `usesig`, `htmlon`, `bbcodeoff`,`smileyoff`, `parseurloff`, `attachment`, `rate`,

discuz X3.1 关于分表 和 分表数据迁移

// *********** 关于读取分表的数据*********** { // forum_thread 分表代码片段 -- 帖子列表 { // 定位某个板块的帖子落在哪个表(forum_thread_0) // ... // 到指定的表(forum_thread_0.forum_thread_1)中,读取帖子列表 // 注意:(分表的时候,要分得刚刚好,同一个板块的帖子不能跨表,不然会查不到) $threadlist = array_merge($threadlist, C::t('foru

如何设置mysql的表不区分你大小写

Linux上安装MySQL默认是数据库的表大小写敏感的.修改很简单,只要该一个mysql的配置文件就可以了. mysql> show tables; +--------------------------------------+ | Tables_in_cddl                       | +--------------------------------------+ | a1_equipment                         | | a1_equipm

【转】busybox分析——arp设置ARP缓存表中的mac地址

[转]busybox分析--arp设置ARP缓存表中的mac地址 转自:http://blog.chinaunix.net/uid-26009923-id-5098083.html 1. 将arp缓存表中某一IP的MAC地址修改 [email protected]:/work/test/tcpip/busy/arp$ cat arp.c #include "utils.h" #include <net/if_arp.h> #include <linux/sockios

百度地图刷新显示不完整(解析加载设置了个延迟,应该是和div顺序有关系)

解决方案:1异步加载(jquery(function(){loadJScript():}))   2解析加载设置了个延迟(setTimeOut(getInit,1000))

discuz首页设置默认地址不带forum.php后缀的方法

最近在研究discuz,上传安装几部搞定,打开首页跳到含有"/forum.php"的网址,到管理中心改了好一会儿也没好.那么如何实现discuz首页设置不带forum.php后缀呢? 我们可以通过空间的控制面板来设置网站首页默认页.登陆空间控制面板,来修改默认页打开的顺序,如下图:

区域设置 ID (LCID) 表, 及获取方法

区域设置 ID (LCID) 表, 及获取方法 中国的区域设置 ID 是 2052, 如果经常打开微软软件的安装目录应该经常见到.获取很简单, 有现成的 API 函数: GetThreadLocale. begin   ShowMessage(IntToStr(GetThreadLocale)); //2052 end; 区域设置 ID (LCID) 表 区域设置描述 简写 十六进制值 十进制值 南非荷兰语 af 0x0436 1078 阿尔巴尼亚语 sq 0x041C 1052 阿拉伯语 -