2016년 6월 24일 금요일

jsUpload 구현한 사이트 입니다.

ASP로 작업해 달라고 해서 공개 게시판인 fsBoard를 사용하였습니다.
Naver SmartEditor + jQueryUpload





<%
If useFile=True And  uploadComponent="jQueryUpload" Then
If fileMaxLimit<0 Then strFileMaxLimit="Unlimited" Else strFileMaxLimit=Int(FormatNumber(fileMaxLimit/1048576,0)) & MsgExtract("WrLabelAttachFileLimit") End If
%>
<!-- 파일 업로드 -->
<input type="hidden" id="jsupload_count" name="jsupload_count">
<style type="text/css">
.fileupload_wrap{width:100%;margin:0;padding:10px 0;border-bottom:1px solid #ddd;}
.preview{width:20px; overflow:hidden; }
.name { width:230px; overflow:hidden; font-size:0.8em; padding-left:5px; }
.size { width:80px; text-align:right; overflow:hidden; font-size:0.8em; padding-right:5px; }
.fileList { width:100%; height:120px; margin-left:30px;margin:0;padding:0;border:1px solid #a0a0a0; overflow:scroll; }
.fileupload-buttonbar {width:96%; }
.table { width:100%; }
.table .delete { width:70px; text-align:left; overflow:hidden; font-size:1em; }
.table .cancel { width:70px; text-align:left; overflow:hidden; font-size:1em; }
.files .progress { width:180px; height:10px; }
.files .start { width:40px; }
.paste { padding-left:170px; }
/* 파일 업로드 프로그래스 바 */
.fileupload-progress .progress { height:5px; margin:0; padding:0; }
.fileupload-progress .progress .bar { height:5px; margin:0; padding:0; }
.fileupload-progress .progress-extended { height:20px; font-size:0.8em; padding: 5 0 5 0; margin:0; }

.btn { padding:0;margin:00; font-size:11px; width:85px; text-decoration: none; position: relative; cursor: pointer; }
.btn span {margin:0;color:#fff;}
.btn span.ui-icon {margin: 0 5px 0 0;position: absolute;left: .2em;top: 50%;margin-top:-8px;}
.btn-icon {margin: 2px; position: relative; padding: 4px 0 4px 0; cursor: pointer; float: left; list-style: none; width:33px; }
.btn-mini { margin:0; position: relative; padding: 0px 0; cursor: pointer; float: left; list-style: none;  width:90px; text-align:center; }
.btn-mini span {  margin:0; color:white; font-size:9px; }
.btn-mini span.ui-icon { margin:0; position: absolute; left: .2em; top: 50%; margin-top: -8px; }
</style>
<div style="width:100%;">
<div class="fileupload_wrap"><!-- bootstrap.min.css 35 line .container width 수정 (init 940px) -->
<form id="fileupload" action="" method="POST" enctype="multipart/form-data">
<noscript><input type="hidden" name="redirect" value=""></noscript>
<div class="row fileupload-buttonbar">
<table width="100%" cellpadding="0" cellspacing="0" border="0">
<tr>
<td width="90" class="le">
<span class="btn fileinput-button">
<i class="icon-plus icon-white"></i>
<span>파일추가</span>
<input type="file" name="files[]" multiple>
</span>
</td>
<td width="90" class="le" style="display:none;">
<button type="submit" class="btn btn-primary start">
<i class="icon-upload icon-white"></i>
<span>전송시작</span>
</button>
</td>
<td width="90" class="le" style="display:none;">
<button type="reset" class="btn btn-warning cancel">
<i class="icon-ban-circle icon-white"></i>
<span>전송취소</span>
</button>
</td>
<td width="120" class="le">
<button type="button" class="btn btn-danger delete">
<i class="icon-trash icon-white"></i>
<span>삭제</span>
</button>
<input type="checkbox" class="toggle margin-left-10">
</td>
<td><%=strFileMaxLimit%></td>
</tr>
</table>
<div class="span5 fileupload-progress fade">
<div class="progress progress-success progress-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100">
<div class="bar" style="width:0%;"></div>
</div>
<div class="progress-extended">&nbsp;</div>
</div>
</div>
<div class="fileupload-loading"></div>
<div class="fileList">
<table role="presentation" class="table table-striped"><tbody class="files" data-toggle="modal-gallery" data-target="#modal-gallery"></tbody></table>
</div>
</form>
<!-- The template to display files available for upload -->
<script id="template-upload" type="text/x-tmpl">
{% for (var i=0, file; file=o.files[i]; i++) { %}
<tr class="template-upload fade">
 <td class="preview"><span class="fade"></span></td>
 <td class="name"><span>{%=decodeURIComponent(file.name)%}</span></td>
 <td class="size"><span>{%=o.formatFileSize(file.size)%}</span></td>
 {% if (file.error) { %}
<td class="error" colspan="2" style="color:red;"><span class="label label-important">&nbsp;Error : </span> {%=decodeURIComponent(file.error)%}</td>
 {% } else if (o.files.valid && !i) { %}
<td class="start">{% if (!o.options.autoUpload) { %}
<button class="btn-icon btn-primary" title="전송">
 <i class="icon-upload icon-white"></i>
 <!--<span>전송</span>-->
</button>
</td>
<td>
<div class="progress progress-success progress-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0"><div class="bar" style="width:0%;"></div></div>
{% } %}</td>
 {% } else { %}
<td colspan="2">&nbsp;</td>
 {% } %}
 <td class="cancel">{% if (!i) { %}
<button class="btn-icon btn-warning" title="취소">
<i class="icon-ban-circle icon-white"></i>
<!--<span>취소</span>-->
</button>
 {% } %}</td>
</tr>
{% } %}
</script>
<!-- The template to display files available for download -->
<script id="template-download" type="text/x-tmpl">
{%
if($("#jsupload_count").val()=="") $("#jsupload_count").val(0);
for (var i=0, file; file=o.files[i]; i++) {
//if($("#jsupload_count").val()=="")
//{
var obj1 = document.createElement("input");
obj1.type="text";
obj1.name="attachFile"+($("#jsupload_count").val()*1+i);
obj1.id="attachFile"+($("#jsupload_count").val()*1+i);
obj1.className="jsuploaded_file";
obj1.value=decodeURIComponent(file.name);
$(obj1).appendTo("#jsupload_files");

var obj2 = document.createElement("input");
obj2.type="text";
obj2.name="attachSize"+($("#jsupload_count").val()*1+i);
obj2.id="attachSize"+($("#jsupload_count").val()*1+i);
obj2.className="jsuploaded_size";
obj2.value=file.size;
$(obj2).appendTo("#jsupload_files");
//}
%}
<tr class="template-download fade">
 {% if (file.error) { %}
<td></td>
<td class="name"><span>{%=file.name%}</span></td>
<!--<td class="size"><span>{%=o.formatFileSize(file.size)%}</span></td>-->
<td class="error" colspan="2"><span class="label label-important">Error</span> {%=file.error%}</td>
 {% } else { %}
<td class="preview">{% if (file.thumbnail_url) { %}
<span><a href="{%=decodeURIComponent(file.url)%}" title="{%=decodeURIComponent(file.name)%}" target="_new"><img src="{%=decodeURIComponent(file.thumbnail_url)%}"></a></span>
{% } %}</td>
<td class="name">
<span><a href="{%=decodeURIComponent(file.url)%}" title="{%=decodeURIComponent(file.name)%}" data-gallery="{%=decodeURIComponent(file.thumbnail_url)&&'gallery'%}" download="{%=decodeURIComponent(file.name)%}">{%=decodeURIComponent(file.name)%}</a></span>
</td>
<td class="size"><span>{%=o.formatFileSize(file.size)%}</span>&nbsp;</td>
<td class="paste" colspan="2">
<button class="btn-mini btn-success btn_paste" tag="{%=decodeURIComponent(file.url)%}" alt="{%=decodeURIComponent(file.name)%}" title="본문삽입">
<i class="icon-circle-arrow-up icon-white"></i>
<span>본문삽입</span>
</button></right>
</td>
{% } %}
<td class="delete">
<button class="btn-icon btn-danger" tag="{%=file.name%}" data-type="{%=file.delete_type%}" data-url="{%=file.delete_url%}"{% if (file.delete_with_credentials) { %} data-xhr-fields='{"withCredentials":true}'{% } %} title="삭제">
<i class="icon-trash icon-white"></i>
<!--<span>삭제</span>-->
</button>
<input type="checkbox" name="delete" value="1">
</td>
</tr>
{% }
$("#jsupload_count").val($("#jsupload_count").val()*1+o.files.length);
%}
</script>
</script>
<script src="<%=FSBOARD_PATH%>jsupload/addon/tmpl.min.js"></script>
<script src="<%=FSBOARD_PATH%>jsupload/addon/load-image.min.js"></script>
<script src="<%=FSBOARD_PATH%>jsupload/addon/canvas-to-blob.min.js"></script>
<script src="<%=FSBOARD_PATH%>jsupload/addon/jquery.image-gallery.min.js"></script>
<script src="<%=FSBOARD_PATH%>jsupload/js/jquery.iframe-transport.js"></script>
<script src="<%=FSBOARD_PATH%>jsupload/js/jquery.fileupload.js"></script>
<script src="<%=FSBOARD_PATH%>jsupload/js/jquery.fileupload-fp.js"></script>
<script src="<%=FSBOARD_PATH%>jsupload/js/jquery.fileupload-ui.js"></script>
<script src="<%=FSBOARD_PATH%>jsupload/js/jquery.fileupload-jui.js"></script>
<script src="<%=FSBOARD_PATH%>jsupload/js/main.js"></script>
<!--[if gte IE 8]><script src="<%=FSBOARD_PATH%>jsupload/js/cors/jquery.xdr-transport.js"></script><![endif]-->
</div>
<%End If%>

게시글 저장시 서버에서 처리하는 방법

'// jQuery 업로드일 경우
If uploadComponent="jQueryUpload" Then
If RequestForm("attachFile0") <> "" Then
tmp = CreateServerFolder(directoryPath & "\" & CInt(seqNum / 100)) ' 게시판 번호 분류 폴더 1/100
If tmp=False Then
Response.Redirect "?id=" & id & "&mode=error&msg=" & Server.UrlEncode(MsgExtract("UploadFolderError")) '"업로드폴더 생성에 실패했습니다."
Response.End
End If
tmp = CreateServerFolder(directoryPath & "\" & CInt(seqNum / 100) & "\" & seqNum) ' 게시판 번호 분류 폴더 1/100
If tmp=False Then
Response.Redirect "?id=" & id & "&mode=error&msg=" & Server.UrlEncode(MsgExtract("UploadFolderError")) '"업로드폴더 생성에 실패했습니다."
Response.End
End If
End If

upUrl = Replace(Replace(directoryPath, Server.MapPath(pathAdjust)&"\.\", ""),"\","/")

For i=0 To (fileMaxNum-1) Step 1
' WriteToFile LogFile, "첨부파일 " & i & " : " & RequestForm("attachFile"&i) & vbCrLf, True
If RequestForm("attachFile"&i) <> "" Then
fileName(i) = SanitizeFileName(RequestForm("attachFile"&i)) '//파일명에 부적합한 문자 제거
fileSize(i) = Replace(RequestForm("attachSize"&i), "'", "")

' 임시저장 폴더로부터 실제 저장폴더로 복사, 임시파일삭제
CopyFile Server.MapPath(pathAdjust&"\jsupload\files")&"\"&RequestForm("unique_key")&"\"&RequestForm("attachFile"&i), directoryPath&"\"&CInt(seqNum / 100)&"\"&seqNum&"\"&fileName(i)  , "delete"

' 섬네일이 있는 경우 임시저장 폴더로부터 실제 저장폴더로 복사, 임시파일삭제
CopyFile Server.MapPath(pathAdjust&"\jsupload\files")&"\"&RequestForm("unique_key")&"\thumb_"&RequestForm("attachFile"&i), directoryPath&"\"&CInt(seqNum / 100)&"\"&seqNum&"\thumb_"&fileName(i) , "delete"

' 에디터 본문에 삽입된 경우 경로 재설정
contents = Replace(contents, "jsupload/files/"&RequestForm("unique_key")&"/"&RequestForm("attachFile"&i), upurl&"/"&CInt(seqNum / 100)&"/"&seqNum&"/"&fileName(i))

' 섬네일이 에디터 본문에 삽입된 경우 경로 재설정
contents = Replace(contents, "jsupload/files/"&RequestForm("unique_key")&"/thumb_"&RequestForm("attachFile"&i), upurl&"/"&CInt(seqNum / 100)&"/"&seqNum&"/thunb_"&fileName(i))
End If
Next

' 임시 업로드 폴더 제거
On Error Resume Next
set objFSO = CreateObject("Scripting.FileSystemObject")
If  objFSO.FolderExists(Server.MapPath("jsupload\files")&"\"&RequestForm("unique_key")) Then
objFSO.DeleteFolder(Server.MapPath("jsupload\files")&"\"&RequestForm("unique_key"))
End If
Set objFSO = Nothing
Err.Clear

2016년 6월 1일 수요일

망보드 게시물 열람시 첨부파일(이미지, 비디오) 내용 첫부분에 나타나게 하기

갤러리가 아니더라도 보통 첨부에 이미지가 있으면 본문내에 넣지 않아도 본문 상단에 표시되기를 원하는 경우가 있습니다.
동영상이 들어있는 경우도 그럴 수 있구요.

아래의 코드는 크롬이 아닌 IE의 경우 OBJECT로 동영상을 보여주는 부분도 추가되어 있습니다.
IE에서는 웬만한 MP4가 재생이 안되는 문제가 발생하여 ffmpeg를 설치하기도 하였으나
실시간 인코딩을 해서 저장하기도 무리가 있고 하여.. IE에서는 OBJECT태그를 사용하도록 하였습니다.

플러그인을 간단하게 만들든지 functions.php 파일 등에 해당 코드를 추가시켜 주시면 됩니다.


/* 망보드 게시물 첨부(이미지/동영상) 표시 */
add_filter('mf_board_item', 'wt_mbw_filter_board_item',1,2);
function wt_mbw_filter_board_item($item,$data=null){
global $mstore,$mb_fields;

if($_REQUEST["mode"]==="view") {
define("MBW_UPLOAD_URL", MBW_CONTENT_URL."/uploads/mangboard/");

if($item["field"]==="fn_content" && $item["type"]==="board")
{
$attach = $mstore->get_board_files(mbw_get_board_item("fn_pid"));
$play = "<center>";
for($v=0;$v<count($attach);$v++)
{
$a = $attach[$v];
if(strpos($a["file_type"], "video")!==false)
{
if(strpos($_SERVER['HTTP_USER_AGENT'], "Trident")!==false) {
$play .= "<p><OBJECT ID='WMPlay".$v."' class='wmp' classid='clsid:22D6F312-B0F6-11D0-94AB-0080C74C7E95' ".
"standby='Loading Microsoft Windows Media Player components...' ".
"type='application/x-oleobject' width='846' height='510'>".
"<param name='Wmode' value='Opaque'>".
"<param name='Filename' value='".MBW_UPLOAD_URL.$a["file_path"]."'>".
"<param name='AutoStart' value='0'>".
"<embed src='".MBW_UPLOAD_URL.$a["file_path"]."' width='846' height='510' allowscriptaccess='always' allowfullscreen='true' wmode='opaque'></embed>".
"</OBJECT></p><p>&nbsp;</p>";
} else {
$play .= "<p><video src='".MBW_UPLOAD_URL.$a["file_path"]."' style='width: 100%; height: 100%;' controls></video></p><p>&nbsp;</p>";
}
}
else if(strpos($a["file_type"], "image")!==false)
{
$play .= "<img src='".MBW_UPLOAD_URL.$a["file_path"]."' width='100%'>";
}
}
$play .= "</center>";

$item["value"]=$play.$item["value"];
}
}
return $item;
}

워드프레스 기본 에디터를 네이버 스마트에디터로 변경

워드프레스 기본 에디터로 작성시 <br>태그가 처리되지 않는 점과 쓰레기코드들이 붙는등
불편함이 있어 네이버 스마트에디터를 기본 에디터로 바꿔버렸습니다.

망보드에 있는 스마트에디터랑 업로드 기능을 사용합니다.
스마트에디터에서 사진업로드를 하면 망보드 파일관리자에 나타납니다.


/* 글 작성에 스마트에디터 사용 : 망보드 스마트에디터 파일 업로드 사용 */
add_filter('the_editor', 'wt_my_editor');
function wt_my_editor($wrapper)
{
echo("<style type='text/css'>.smartEditor { width:99%; }</style>");
$html = "<link href='/wp-content/plugins/mangboard/plugins/editors/smart/css/default.css' rel='stylesheet' type='text/css' />";
$html .= "<script type='text/javascript' src='/wp-content/plugins/mangboard/plugins/editors/smart/js/HuskyEZCreator.js?ver=4.5.2'></script>";
$html .= "<script type='text/javascript'>
var oEditors=[];
nhn.husky.EZCreator.createInIFrame({
oAppRef: oEditors,
elPlaceHolder: 'content',
sSkinURI:'/wp-content/plugins/mangboard/plugins/editors/smart/SmartEditor2Skin.html',
fCreator: 'createSEditor2'});

jQuery(document).ready(function() {
jQuery('#post').on('submit', function() {
oEditors.getById['content'].exec('UPDATE_CONTENTS_FIELD', []);
this.submit();
});
jQuery('#edButtonHTML').remove();
});
</script>";
$html .= "<div id='smartEditor'><textarea class='smartEditor' rows='10' cols='*' name='content' tabindex='2' id='content'>%s</textarea></div>";

return $html;
}

/* html 퀵태그 숨김 */
add_filter('wp_editor_settings', 'wt_editor_settings');
function wt_editor_settings($settings) {
$settings['quicktags'] = false;
return $settings;
}

/* 워드프레스 리치에디터 사용 금지 */
add_filter( 'user_can_richedit', 'wt_patrick_user_can_richedit');
function wt_patrick_user_can_richedit($c) {
return false;
    global $post_type;
    if ('post' == $post_type)
        return false;
    return $c;
}