管理界面通过行政办公查看工作日志时,附件无法下载预览等操作。
重写了配置文件的附件路径为:$ATTACH_PATH2=”../attach/”;
attach目录位于网站根目录。
由于有了之前的经验,知道可能会因为编码问题导致中文BUG,所以遇到此问题时,第一时间从编码入手尝试解决。
1.解密inc下的attach.php文件,根据“您所访问的文件不存在”定位,向上找到函数是判定文件是否存在的,这时看到了路径的变量$URL,进入附件目录发现路径有中文,看来是编码问题,于是尝试在

$URL = $ATTACH_PATH.$ATTACHMENT_ID."/".$ATTACHMENT_NAME;

的下面加了一句编码转换:

$URL=iconv('GB2312','UTF-8',$URL);

将路径转码一下。
2.之后出现提示“此图片为CMYK色彩模式”,检查代码发现看来已经找到了文件,都过了后缀检测的部分,但是这个彩色模式的部分没有相关函数判定直接输出,所以直接注释掉。
注释掉的代码示意图
注释掉的代码示意图
3.改完之后发现这个文件下载,图片类型的竟然直接就显示了,不提示下载,发现$COTENT_TYPE默认都是0,对于下载和预览的差异没有判定,所以自作主张加入了获取预览标志的变量,通过判定变量是否为1来确定是否是预览,不是预览则$COTENT_TYPE为1,是则为0。
获取预览标志示意图
获取预览标志示意图
4.把在每一个单独的$COTENT_TYPE = 0;替换为if($DIRECT_VIEW==1){$COTENT_TYPE = 0;}else{$COTENT_TYPE = 1;},不多,手动替换即可,这样不会出错,用三元运算符也可以。表达的意思就是上面说的。
5.修改之后,文件源码如下:

<?php
/*********************/
/* */
/* Version : 5.1.0 */
/* Author : RM */
/* Comment : 071223 */
/* */
/*********************/
include_once( "inc/auth.php" );
include_once( "inc/utility_file.php" );
$DIRECT_VIEW=$_GET["DIRECT_VIEW"];
$FB_STR1 = urldecode( $ATTACHMENT_NAME );
if ( stristr( $MODULE, "/" ) || stristr( $MODULE, "\\" ) || stristr( $YM, "/" ) || stristr( $YM, "\\" ) || stristr( $ATTACHMENT_ID, "/" ) || stristr( $ATTACHMENT_ID, "\\" ) || stristr( $FB_STR1, "/" ) || stristr( $FB_STR1, "\\" ) )
{
message( "错误", "参数含有非法字符。" );
exit( );
}
$ATTACHMENT_ID_OLD = $ATTACHMENT_ID;
$ATTACHMENT_ID = attach_id_decode( $ATTACHMENT_ID, $ATTACHMENT_NAME );
$MYOA_ATTACHMENT_NAME = $ATTACHMENT_NAME;
if ( $MODULE != "" && $YM != "" )
{
$URL = $ATTACH_PATH2.$MODULE."/".$YM."/".$ATTACHMENT_ID.".".$ATTACHMENT_NAME;
}
else
{
$URL = $ATTACH_PATH.$ATTACHMENT_ID."/".$ATTACHMENT_NAME;
}
$URL=iconv('GB2312','UTF-8',$URL);//时鹏亮2013.6.13解决附件无法查找中文提示找不到文件
if ( !file_exists( $URL ) )
{
if ( $MODULE == "" && $YM == "" )
{
$ATTACHMENT_ID = ( $ATTACHMENT_ID_OLD - 2 ) / 3;
$URL = $ATTACH_PATH.$ATTACHMENT_ID."/".$ATTACHMENT_NAME;
if ( !file_exists( $URL ) )
{
echo "文件名:".$MYOA_ATTACHMENT_NAME."<br>抱歉,您所访问的文件不存在,可能已经被删除或转移,请联系OA管理员。<br>error code:1";
button_back( );
exit( );
}
}
else
{
echo "文件名:".$MYOA_ATTACHMENT_NAME."<br>抱歉,您所访问的文件不存在,可能已经被删除或转移,请联系OA管理员。<br>";
button_back( );
exit( );
}
}
$file_ext = strtolower( substr( $MYOA_ATTACHMENT_NAME, strpos( $MYOA_ATTACHMENT_NAME, "." ) ) );
if ( is_office( $FB_STR1 ) )
{
oc_log( trim( $YM."_".$ATTACHMENT_ID, "_" ), $FB_STR1, 3 );
}
switch ( $file_ext )
{
case ".jpg" :
case ".jpeg" :
if($DIRECT_VIEW==1){$COTENT_TYPE = 0;}else{$COTENT_TYPE = 1;}//时鹏亮2013.6.14添加检测是否预览
$COTENT_TYPE_DESC = "image/jpeg";
$img_info = getimagesize( $URL );
if ( !( $img_info['channels'] == 4 ) && !( 0 < stripos( $_SERVER['HTTP_USER_AGENT'], "MSIE 6.0" ) ) || !( 0 < stripos( $_SERVER['HTTP_USER_AGENT'], "MSIE 7.0" ) ) || !( 0 < stripos( $_SERVER['HTTP_USER_AGENT'], "MSIE 8.0" ) ) )
{
break;
}
$CMYK = TRUE;
break;
case ".bmp" :
if($DIRECT_VIEW==1){$COTENT_TYPE = 0;}else{$COTENT_TYPE = 1;}//时鹏亮2013.6.14添加检测是否预览
$COTENT_TYPE_DESC = "image/bmp";
break;
case ".gif" :
if($DIRECT_VIEW==1){$COTENT_TYPE = 0;}else{$COTENT_TYPE = 1;}//时鹏亮2013.6.14添加检测是否预览
$COTENT_TYPE_DESC = "image/gif";
break;
case ".jpg" :
if($DIRECT_VIEW==1){$COTENT_TYPE = 0;}else{$COTENT_TYPE = 1;}//时鹏亮2013.6.14添加检测是否预览
$COTENT_TYPE_DESC = "image/png";
break;
case ".html" :
case ".htm" :
if($DIRECT_VIEW==1){$COTENT_TYPE = 0;}else{$COTENT_TYPE = 1;}//时鹏亮2013.6.14添加检测是否预览
$COTENT_TYPE_DESC = "text/html";
break;
case ".wmv" :
case ".wav" :
case ".mid" :
case ".mht" :
if($DIRECT_VIEW==1){$COTENT_TYPE = 0;}else{$COTENT_TYPE = 1;}//时鹏亮2013.6.14添加检测是否预览
$COTENT_TYPE_DESC = "application/octet-stream";
break;
case ".pdf" :
if($DIRECT_VIEW==1){$COTENT_TYPE = 0;}else{$COTENT_TYPE = 1;}//时鹏亮2013.6.14添加检测是否预览
$COTENT_TYPE_DESC = "application/pdf";
break;
case ".swf" :
if($DIRECT_VIEW==1){$COTENT_TYPE = 0;}else{$COTENT_TYPE = 1;}//时鹏亮2013.6.14添加检测是否预览
$COTENT_TYPE_DESC = "application/x-shockwave-Flash";
break;
$COTENT_TYPE = 1;
$COTENT_TYPE_DESC = "application/octet-stream";
case ".doc" :
case ".dot" :
$COTENT_TYPE = $ATTACH_OFFICE_OPEN_IN_IE ? 0 : 1;
$COTENT_TYPE_DESC = $ATTACH_OFFICE_OPEN_IN_IE ? "application/msword" : "application/octet-stream";
break;
case ".xls" :
case ".xlc" :
case ".xll" :
case ".xlm" :
case ".xlw" :
case ".csv" :
$COTENT_TYPE = $ATTACH_OFFICE_OPEN_IN_IE ? 0 : 1;
$COTENT_TYPE_DESC = $ATTACH_OFFICE_OPEN_IN_IE ? "application/msExcel" : "application/octet-stream";
break;
case ".ppt" :
case ".pot" :
case ".pps" :
case ".ppz" :
$COTENT_TYPE = $ATTACH_OFFICE_OPEN_IN_IE ? 0 : 1;
$COTENT_TYPE_DESC = $ATTACH_OFFICE_OPEN_IN_IE ? "application/mspowerpoint" : "application/octet-stream";
break;
case ".docx" :
case ".dotx" :
case ".xlsx" :
case ".xltx" :
case ".pptx" :
case ".potx" :
case ".ppsx" :
$COTENT_TYPE = $ATTACH_OFFICE_OPEN_IN_IE ? 0 : 1;
$COTENT_TYPE_DESC = $ATTACH_OFFICE_OPEN_IN_IE ? "application/vnd.openxmlformats" : "application/octet-stream";
break;
case ".rm" :
case ".rmvb" :
$COTENT_TYPE = 1;
$COTENT_TYPE_DESC = "audio/x-pn-realaudio";
break;
$COTENT_TYPE = 1;
$COTENT_TYPE_DESC = "application/octet-stream";
}
/*echo "此图片为CMYK色彩模式,您当前浏览器不支持此格式图片显示,请转换为RGB模式。";
button_back( );
exit( );*/
ob_end_clean( );
header( "Cache-control: private" );
header( "Content-type: ".$COTENT_TYPE_DESC );
header( "Accept-Ranges: bytes" );
header( "Content-Length: ".sprintf( "%u", filesize( $URL ) ) );
if ( stristr( $HTTP_USER_AGENT, "MSIE" ) && $ATTACH_UTF8 )
{
$MYOA_ATTACHMENT_NAME = urlencode( iconv( ini_get( "default_charset" ), "utf-8", $MYOA_ATTACHMENT_NAME ) );
}
if ( $COTENT_TYPE == 1 )
{
header( "Content-Disposition: attachment; filename=\"".$MYOA_ATTACHMENT_NAME."\"" );
}
else
{
header( "Content-Disposition: filename=\"".$MYOA_ATTACHMENT_NAME."\"" );
}
$handle = fopen( $URL, "rb" );
$contents = "";
while ( !feof( $handle ) )
{
echo $contents = fread( $handle, 8192 );
}
fclose( $handle );
?>

如此,附近问题得以解决。

PS:后续我想了下,既然环境导致对中文支持不佳,其实也可以在/general/diary/update.php里添加代码判定下是否含有中文,有则提示修改问英文,代码如下:

if (preg_match("/[\x7f-\xff]/", $ATTACHMENT_NAME)) {
message( "温馨提示", "文件名含有中文容易引起路径异常,请去掉中文部分重新提交,谢谢,给您带来的不便请谅解。" );
button_back( );
exit( );
}

然后修改inc/attach.php文件,在$MYOA_ATTACHMENT_NAME = $ATTACHMENT_NAME;的下一行添加:

if (preg_match("/[\x7f-\xff]/", $ATTACHMENT_NAME)) {
$ATTACHMENT_NAME=iconv('EUC-CN','UTF-8',$ATTACHMENT_NAME);
}

如此判定下文件名即可。attach.php的其他的部分其实就不需要改了。

Related Posts: 通达office anywhere2010-windows迁移Nginx后附件无法读取的修正过程 :