在手机触屏版里的论坛页里所有的上传图片均以小图形式显示:如果插入贴子的话都显示成长宽不超过140px的小图,而没插入的话都显示成长宽不超过83px的小图。而点击一下一个小图后,屏幕上会单独显示原始尺寸的图片,但最大不超出屏幕的范围。而且可以左右划动来看该页上其它上传图片的大图。据网友牛肉炖土豆提议将该论坛页里的网络图片也加入这个大图显示页。
http://www.bian-wang.com/discuz/home.php?mod=space&uid=10744&do=blog&id=2039 。本文讨论下如何解决这个问题。
先排查下相关网页所使用的脚本代码和模板:
脚本文件 source/module/forum/forum_viewthread.php,它使用定义在 source/function/function_attachment.php 里的函数 parseattach 来将储存的贴子内容里的上传图片bbcode找出来,而 parseattach 对找到的上传图片内容用定义在 template/touch/forum/discuzcode.htm 里的函数 attachinpost 将其转换成HTML代码。同时它使用定义在 source/function/function_discuzcode.php 里的函数 discuzcode 来将储存的贴子内容里的网络图片bbcode找出来,而 discuzcode 对找到的网络图片内容用定义在同一文件里的函数 parseimg 将其转换成HTML代码。
模板文件:template/default/touch/forum/viewthread.htm
脚本文件 source/module/forum/forum_viewthread.php 调用了 source/include/thread/thread_album.php。
模板文件:template/default/touch/forum/viewthread_album.htm
先分析下第一张图:显示一个主题。假设我们在该主题贴或它下面的一个贴子里加入了文字,两张上传图片和一张网络图片,那么该贴的内容存在数据库里的形式类似于:
Test
[attach]1[/attach]
[img=150,100]http://www.xyz.org/a.jpg[/img]
[attach]2[/attach]
而在显示时从数据库里将内容取出后经过转换成为了供显示用的HTML代码,类似于:
Test
< a href="forum.php?mod=viewthread&tid=3&aid=1&from=album&page=1">
< a href="forum.php?mod=viewthread&tid=3&aid=2&from=album&page=1">
帖子里有关上传图片的内容是用bbcode标签attach记载在数据库里的,转换它们的函数是attachinpost,它将bbcode内容转换成一个HTML的img元素外套一个超链。而有关网络图片的内容是用bbcode标签img记载的,转换它们的函数是parseimg,它将bbcode内容转换成一个HTML的img元素但不带外套。
下面是修改内容:
1) 首先要对处理论坛页显示的主要的脚本文件 source/module/forum/forum_viewthread.php 做多处改动:
1a) 先修改支持大图显示的条件:将下面这句
} elseif($_GET['from'] == 'album' && ($_G['setting']['guestviewthumb']['flag'] && !$_G['uid'] && IN_MOBILE != 2 || !$_G['group']['allowgetimage'])) {
改成
} elseif($_GET['from'] == 'album' && IN_MOBILE != 2 && ($_G['setting']['guestviewthumb']['flag'] && !$_G['uid'] || !$_G['group']['allowgetimage'])) {
注意可用IN_MOBILE是否是2来判断是否在使用触屏版,这个条件下面将多次使用。
1b) 为了将上传图片和网络图片在大图显示页上按它们在论坛页上出现的先后次序显示,我们必须找到当前页里的所有上传图片和网络图片及其排序。在下面这句
$_G['allblocked'] = true;
前加入
if (IN_MOBILE == 2) {
foreach($postlist as $pid=>$post) {
$imgattvaluelist = array();
preg_match_all("/\[attach\](\d+)\[\/attach\]|\[img\]\s*([^\[\<\r\n]+?)\s*\[\/img\]|\[img=\d{1,4}[x|\,]\d{1,4}\]\s*([^\[\<\r\n]+?)\s*\[\/img\]/is", $post['message'], $results);
foreach($results[0] as $k => $result)
{
for ($i=1; $i<=3; $i++) {
if (!empty($results[$i][$k])) {
if ($_G['group']['allowgetimage'] || $i>1) $imgattvaluelist[] = $results[$i][$k];
}
}
}
$postlist[$pid]['imgattvaluelist'] = $imgattvaluelist;
}
}
注意我们在调用discuzcode前运行这段代码,因为从帖子的bbcode内容里找到上传图片的附件ID和网络图片的地址比在html里找容易。
1c) 给网络图片套上超链:在下面这句
if($_G['forum_attachpids'] && !defined('IN_ARCHIVER')) {
前加入
if (IN_MOBILE == 2) {
foreach($postlist as $pid => $post) {
$postlist[$pid]['message'] = preg_replace_callback("/\ /is", array(new image_add_hyperlink_callback($post['imgattvaluelist']), 'callback'), $post['message']);
}
}
1d) 再在这个文件的末端添加一个上面这句里用到的callback类:
class image_add_hyperlink_callback {
private $imagelist;
function __construct($imagelist) {
$this->imagelist = $imagelist;
}
public function callback($matches) {
global $_G;
preg_match('/src=["\']([^"\']+)/i',$matches[1], $result);
if (!empty($result)) {
$key = array_search($result[1], $this->imagelist);
if ($key !== false) {
return '< a href="forum.php?mod=viewthread&tid='.$_G['tid'].'&aid='.urlencode($result[1]).'&from=album&page='.$_G[page].'" class="orange">' .$matches[0] .'';
}
}
return $matches[0];
}
}
这里值得注意的是我们不能给帖子里的所有图片都加超链,因为有些图片是Discuz添加的,如显示附件的icon。所以我们要检查在帖子里找到的每个图片是否属于前面我们找到的附件及网络图片列。
1e) 还要加上没有插入的上传图片:在下面这句前
if(empty($postlist)) {
加入
if (IN_MOBILE == 2 && $_G['group']['allowgetimage']) {
foreach($postlist as $pid=>$post) {
foreach($post['imagelist'] as $image) {
$postlist[$pid]['imgattvaluelist'][] = $image;
}
}
}
2) 前面得到的是附件ID和网络图片地址列,还需要将不是图片的附件从该列里去掉。修改脚本文件 source/include/thread/thread_album.php ,在下面这句
if(empty($imglist)) {
前加入
if (IN_MOBILE == 2) {
$imgattvaluelist = array();
foreach($postlist as $pid=>$post) {
$imgattvaluelist = array_merge($imgattvaluelist, $post['imgattvaluelist']);
}
$imgattvaluelist = array_unique($imgattvaluelist);
$timglist = $imglist;
$imglist = array();
foreach ($imgattvaluelist as $value) {
if (ctype_digit($value)) {
$key = array_search($value, $timglist['aid']);
if ($key !== false) {
$imglist['aid'][] = $value;
$imglist['url'][] = $timglist['url'][$key];
}
}
else {
$imglist['aid'][] = null;
$imglist['url'][] = $value;
}
}
}
3) 最后要修改对应于触屏版的大图显示页的模板文件 template/default/touch/forum/viewthread_album.htm。
3a) 将下面这句
改为
3b) 将下面这句
改为
3c) 再将下面这句
改为
相关修改文件下载(适用于Discuz 3.4版):
http://www.bian-wang.com/discuz/data/userupload/10005/touch_preview_remote_images.zip
注:本文中的代码里的<符号后和a相连时加了一个不应该有的空格,以避免Discuz在保存日志时自动改变日志内容。