From 7df9c7eb8eb7f2a80d040aba642dd169be9cca51 Mon Sep 17 00:00:00 2001 From: zero Date: Fri, 24 Oct 2008 09:39:36 +0000 Subject: [PATCH] =?UTF-8?q?SWFUploader=20=EB=B2=84=EC=A0=84=20=EC=97=85?= =?UTF-8?q?=EA=B7=B8=EB=A0=88=EC=9D=B4=EB=93=9C.=20Flash10=EC=97=90=20?= =?UTF-8?q?=EB=94=B0=EB=A5=B8=20=ED=8C=8C=EC=9D=BC=EC=97=85=EB=A1=9C?= =?UTF-8?q?=EB=93=9C=20=EB=8F=99=EC=9E=91=20=EC=98=A4=EB=A5=98=20=EC=88=98?= =?UTF-8?q?=EC=A0=95.=20=EB=82=B4=EB=B6=80=EC=A0=81=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=ED=8C=8C=EC=9D=BC=EC=97=85=EB=A1=9C=EB=93=9C=EC=99=80=20?= =?UTF-8?q?=EA=B8=80/=EB=8C=93=EA=B8=80/=ED=8E=98=EC=9D=B4=EC=A7=80?= =?UTF-8?q?=EC=9D=98=20=EA=B4=80=EA=B3=84=20=EA=B5=AC=EC=A1=B0=20=EA=B0=9C?= =?UTF-8?q?=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://xe-core.googlecode.com/svn/sandbox@4680 201d5d3c-b55e-5fd7-737f-ddc643e51545 --- index.php | 1 - modules/board/board.view.php | 5 - modules/comment/comment.controller.php | 2 +- modules/editor/editor.controller.php | 9 +- modules/editor/editor.model.php | 17 +- modules/editor/skins/default/editor.html | 35 +- modules/editor/tpl/images/SWFUpload.swf | Bin 1954 -> 11141 bytes modules/editor/tpl/js/swfupload.js | 889 ++++++++++++++++++++++ modules/editor/tpl/js/uploader.js | 485 ++++++------ modules/file/conf/module.xml | 2 + modules/file/file.admin.view.php | 8 +- modules/file/file.controller.php | 3 +- modules/file/file.model.php | 41 +- modules/page/tpl/page_content_modify.html | 2 +- modules/poll/poll.admin.model.php | 2 +- modules/widget/tpl/js/widget.js | 4 +- modules/widget/widget.admin.view.php | 1 - 17 files changed, 1229 insertions(+), 277 deletions(-) create mode 100644 modules/editor/tpl/js/swfupload.js diff --git a/index.php b/index.php index d94cc371f..6a7bd02c1 100644 --- a/index.php +++ b/index.php @@ -63,5 +63,4 @@ $oModuleHandler->init(); $oModule = &$oModuleHandler->procModule(); $oModuleHandler->displayContent($oModule); - ?> diff --git a/modules/board/board.view.php b/modules/board/board.view.php index 579e42df6..310b157ad 100644 --- a/modules/board/board.view.php +++ b/modules/board/board.view.php @@ -280,11 +280,6 @@ $oDocument = $oDocumentModel->getDocument(0, $this->grant->manager); $oDocument->setDocument($document_srl); - if(!$oDocument->isExists()) { - $document_srl = getNextSequence(); - Context::set('document_srl',$document_srl); - } - // 글을 수정하려고 할 경우 권한이 없는 경우 비밀번호 입력화면으로 if($oDocument->isExists()&&!$oDocument->isGranted()) return $this->setTemplateFile('input_password_form'); diff --git a/modules/comment/comment.controller.php b/modules/comment/comment.controller.php index b8fc647fe..926ce5fa5 100644 --- a/modules/comment/comment.controller.php +++ b/modules/comment/comment.controller.php @@ -122,7 +122,7 @@ // 순서를 정함 $obj->list_order = getNextSequence() * -1; - // 내용에서 제로보드XE만의 태그를 삭제 + // 내용에서 XE만의 태그를 삭제 $obj->content = preg_replace('!<\!--(Before|After)(Document|Comment)\(([0-9]+),([0-9]+)\)-->!is', '', $obj->content); if(!$obj->regdate) $obj->regdate = date("YmdHis"); diff --git a/modules/editor/editor.controller.php b/modules/editor/editor.controller.php index 15381264b..a37389a3b 100644 --- a/modules/editor/editor.controller.php +++ b/modules/editor/editor.controller.php @@ -23,6 +23,12 @@ $args->document_srl = Context::get('document_srl'); $args->content = Context::get('content'); $args->title = Context::get('title'); + $output = $this->doSaveDoc($args); + + $this->setMessage('msg_auto_saved'); + } + + function doSaveDoc($args) { if(Context::get('is_logged')) { $logged_info = Context::get('logged_info'); @@ -32,8 +38,7 @@ } // 저장 - $output = executeQuery('editor.insertSavedDoc', $args); - $this->setMessage('msg_auto_saved'); + return executeQuery('editor.insertSavedDoc', $args); } /** diff --git a/modules/editor/editor.model.php b/modules/editor/editor.model.php index b814328f1..4dbdae9f4 100644 --- a/modules/editor/editor.model.php +++ b/modules/editor/editor.model.php @@ -97,8 +97,7 @@ **/ if($enable_autosave) { // 자동 저장된 데이터를 추출 - $saved_doc = $this->getSavedDoc(); - if($saved_doc->document_srl && !$upload_target_srl) $upload_target_srl = $saved_doc->document_srl; + $saved_doc = $this->getSavedDoc($upload_target_srl); // 자동 저장 데이터를 context setting Context::set('saved_doc', $saved_doc); @@ -123,8 +122,8 @@ // SWFUploader에 세팅할 업로드 설정 구함 $file_config = $oFileModel->getUploadConfig(); - $file_config->attached_size = $file_config->allowed_attach_size*1024; - $file_config->allowed_filesize = $file_config->allowed_filesize*1024; + $file_config->attached_size = $file_config->allowed_attach_size*1024*1024; + $file_config->allowed_filesize = $file_config->allowed_filesize*1024*1024; Context::set('file_config',$file_config); @@ -308,7 +307,7 @@ /** * @brief 자동저장되어 있는 정보를 가져옴 **/ - function getSavedDoc() { + function getSavedDoc($upload_target_srl) { // 로그인 회원이면 member_srl, 아니면 ipaddress로 저장되어 있는 문서를 찾음 if(Context::get('is_logged')) { $logged_info = Context::get('logged_info'); @@ -334,8 +333,14 @@ if($saved_doc->document_srl) { $module_srl = Context::get('module_srl'); $oFileController = &getController('file'); - $oFileController->moveFile($saved_doc->document_srl, $module_srl, $saved_doc->document_srl); + $oFileController->moveFile($saved_doc->document_srl, $module_srl, $upload_target_srl); } + $saved_doc->document_srl = $upload_target_srl; + + // 자동 저장 데이터 변경 + $oEditorController = &getController('editor'); + $oEditorController->deleteSavedDoc(); + $oEditorController->doSaveDoc($saved_doc); return $saved_doc; } diff --git a/modules/editor/skins/default/editor.html b/modules/editor/skins/default/editor.html index 1ec1033a4..64992abc6 100644 --- a/modules/editor/skins/default/editor.html +++ b/modules/editor/skins/default/editor.html @@ -144,15 +144,24 @@ - + + - @@ -161,12 +170,12 @@ @@ -175,14 +184,12 @@ - - diff --git a/modules/editor/tpl/images/SWFUpload.swf b/modules/editor/tpl/images/SWFUpload.swf index c423737a53f2fbea1697944827cb4e7e3923c74a..a8178beec7baac9989150cad7464dca0402c7dad 100644 GIT binary patch literal 11141 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 Xy!bnA4gTxf(*LdF8tDBmpq)oT?|E;l literal 1954 zcmV;T2VM9>S5pXy761Tv+SOP~bKBMxJ^(=pdeO3^ly$5mlGDVI>2*$box$=0sa*={5;C6;uopn;bGCPd|}r`xLWZW zs|~x+@V(XWS*_J{eY?6^{&edTrr<2|w|TOEv2J_@s0&gT5?$!%9@bs|$abM{^tq@+ zV7spWOjNfVS41aG5yD~M`-AMf2rGfpj2!f8w<2FTYuL}7Myo+;q4Qe-vbQp;ss_n& zwpS5u4xJuhMoN%(Y}c<36|s%qXkzDLi0DZW_`wkV)0Sw7YM-DO`1L@9VIP}y2l}YF zc6hvp;sH10zZ}^?l<@CB`6P@)142=01x|D#LCgCM+ws74Q09pMd{3sR{HR7=xT0=H z0xE%^AJkH@#Cmbl_u>rt5<bLgyuoBg?PlXVo5x&2vH4} z)TCN+orV*wLKI+V4x0L26!b$Lk35)dAEc)vFO<8kuf6(FR zniO+mfpv|=_5`xVY2`B08-;FrR(my8BY{QA+E8WL8JjHinn*Dk>OF>i@=mO$CaLKw z@G{jN14A>%%yHHovkH=7Dux*|CKO{LW=tx^WXzaSjH#G0tr*iWV@5G%Vn#+WGBM+t zVqA+Evx+erGp;Mf^_VfI7;`aWUNPol#)4ujAOkUaWt_GT^Lxz8G9ceCW!na+-muWb zd=;sigr}j6>!dqa?nVB-Rw{Jcy^hoySFl?`YWWIww~%`C3U)t0>a8o-y^YlEE7-k* z)XKNDn*gp8Htw+O-MB_~t@afEj;F}id+ckKb$-a-_hZd9rMWgz^PbYYH&XMy(!4)X zbDo<&vf61m_v815bTc!@V{G%o!vW~rh`{{1$11M{{ih; zmB%{&7`pjkDfUB=r?O-(ll(dRdSFRU52(-Fd6d$m>*GfgRowKf4HBrP%|p+DH3TVptz@t60F) zzdTDS@+Xke9Q~tIS}hENVZQ@9|K@1AA^7B$%Gy_g1xCv_7p;MHQSYpXQ{CJ(E>{k| zy9(V*7LVBL%tc;jF6Z@)(+sU5Sa+R{h;XdTGsAp8fD6IPj95#PX{4F?B!D+hZ(ve1 zt7QPG<0xv%lYNQHoEq98HvWw_Q97)QD%r4J-|9>IFObx5FzxMg)5gX>yQ8>p?&c{S z^T~OR{`EhkvwV6R=PvIB62zmENQClc2nII}{0Q$lzgBr(AC~7Pv?qCiKEK4*M?|OM zxqW)Gx2S>&s%{I#i{SkG<=`BO!pi9@RMaumD_$V@>hPsTVjVY7xhbfWv61fV80jLn zDYCSYiuZ~IHcc66OKy#L<}l*@c&kJjzlR>CTphPdJ-b4@K+O&V{h+fzjS=|6R@lKh z%#I#zWgc!jmvM=WuP-6>M2rB86bMx z$~{yOZ1pV^AF4zqJ5|K|Cut0&wU>O0vvXVWNvR`f}55Llt z;6~@#+H=U@Mou;4H8c$ckk5dcdIo%tp8>Uz&w$BO(pl!u8kxU1hMD27fQf3~BVgyD zMLkE^LA})wUKE0V^f}a8UIpxC(>>{bbhz-%;5F_4=glB>LoQ(P)nu&uYBGL0Pm@Mp z28Ki8aR<~~T!z;<0#m*tEGAp_qZ33md5LUj@-vYTXvh!2kdN diff --git a/modules/editor/tpl/js/swfupload.js b/modules/editor/tpl/js/swfupload.js new file mode 100644 index 000000000..40622498e --- /dev/null +++ b/modules/editor/tpl/js/swfupload.js @@ -0,0 +1,889 @@ +/** + * SWFUpload: http://www.swfupload.org, http://swfupload.googlecode.com + * + * mmSWFUpload 1.0: Flash upload dialog - http://profandesign.se/swfupload/, http://www.vinterwebb.se/ + * + * SWFUpload is (c) 2006-2007 Lars Huring, Olov Nilzn and Mammon Media and is released under the MIT License: + * http://www.opensource.org/licenses/mit-license.php + * + * SWFUpload 2 is (c) 2007-2008 Jake Roberts and is released under the MIT License: + * http://www.opensource.org/licenses/mit-license.php + * + */ + + +/* ******************* */ +/* Constructor & Init */ +/* ******************* */ + +var SWFUpload = function (settings) { + this.initSWFUpload(settings); +}; + +SWFUpload.prototype.initSWFUpload = function (settings) { + try { + this.customSettings = {}; // A container where developers can place their own settings associated with this instance. + this.settings = settings; + this.eventQueue = []; + this.movieName = "SWFUpload_" + SWFUpload.movieCount++; + this.movieElement = null; + + // Setup global control tracking + SWFUpload.instances[this.movieName] = this; + + // Load the settings. Load the Flash movie. + this.initSettings(); + this.loadFlash(); + this.displayDebugInfo(); + } catch (ex) { + delete SWFUpload.instances[this.movieName]; + throw ex; + } +}; + +/* *************** */ +/* Static Members */ +/* *************** */ +SWFUpload.instances = {}; +SWFUpload.movieCount = 0; +SWFUpload.version = "2.2.0 Alpha"; +SWFUpload.QUEUE_ERROR = { + QUEUE_LIMIT_EXCEEDED : -100, + FILE_EXCEEDS_SIZE_LIMIT : -110, + ZERO_BYTE_FILE : -120, + INVALID_FILETYPE : -130 +}; +SWFUpload.UPLOAD_ERROR = { + HTTP_ERROR : -200, + MISSING_UPLOAD_URL : -210, + IO_ERROR : -220, + SECURITY_ERROR : -230, + UPLOAD_LIMIT_EXCEEDED : -240, + UPLOAD_FAILED : -250, + SPECIFIED_FILE_ID_NOT_FOUND : -260, + FILE_VALIDATION_FAILED : -270, + FILE_CANCELLED : -280, + UPLOAD_STOPPED : -290 +}; +SWFUpload.FILE_STATUS = { + QUEUED : -1, + IN_PROGRESS : -2, + ERROR : -3, + COMPLETE : -4, + CANCELLED : -5 +}; +SWFUpload.BUTTON_ACTION = { + SELECT_FILE : -100, + SELECT_FILES : -110, + START_UPLOAD : -120 +}; + +/* ******************** */ +/* Instance Members */ +/* ******************** */ + +// Private: initSettings ensures that all the +// settings are set, getting a default value if one was not assigned. +SWFUpload.prototype.initSettings = function () { + this.ensureDefault = function (settingName, defaultValue) { + this.settings[settingName] = (this.settings[settingName] == undefined) ? defaultValue : this.settings[settingName]; + }; + + // Upload backend settings + this.ensureDefault("upload_url", ""); + this.ensureDefault("file_post_name", "Filedata"); + this.ensureDefault("post_params", {}); + this.ensureDefault("use_query_string", false); + this.ensureDefault("requeue_on_error", false); + + // File Settings + this.ensureDefault("file_types", "*.*"); + this.ensureDefault("file_types_description", "All Files"); + this.ensureDefault("file_size_limit", 0); // Default zero means "unlimited" + this.ensureDefault("file_upload_limit", 0); + this.ensureDefault("file_queue_limit", 0); + + // Flash Settings + this.ensureDefault("flash_url", "swfupload.swf"); + this.ensureDefault("prevent_swf_caching", true); + + // Button Settings + this.ensureDefault("button_image_url", ""); + this.ensureDefault("button_width", 1); + this.ensureDefault("button_height", 1); + this.ensureDefault("button_text", ""); + this.ensureDefault("button_text_style", "color: #000000; font-size: 16pt;"); + this.ensureDefault("button_text_top_padding", 0); + this.ensureDefault("button_text_left_padding", 0); + this.ensureDefault("button_action", SWFUpload.BUTTON_ACTION.SELECT_FILES); + this.ensureDefault("button_disabled", false); + this.ensureDefault("button_placeholder_id", null); + + // Debug Settings + this.ensureDefault("debug", false); + this.settings.debug_enabled = this.settings.debug; // Here to maintain v2 API + + // Event Handlers + this.settings.return_upload_start_handler = this.returnUploadStart; + this.ensureDefault("swfupload_loaded_handler", null); + this.ensureDefault("file_dialog_start_handler", null); + this.ensureDefault("file_queued_handler", null); + this.ensureDefault("file_queue_error_handler", null); + this.ensureDefault("file_dialog_complete_handler", null); + + this.ensureDefault("upload_start_handler", null); + this.ensureDefault("upload_progress_handler", null); + this.ensureDefault("upload_error_handler", null); + this.ensureDefault("upload_success_handler", null); + this.ensureDefault("upload_complete_handler", null); + + this.ensureDefault("debug_handler", this.debugMessage); + + this.ensureDefault("custom_settings", {}); + + // Other settings + this.customSettings = this.settings.custom_settings; + + // Update the flash url if needed + if (this.settings.prevent_swf_caching) { + this.settings.flash_url = this.settings.flash_url + "?swfuploadrnd=" + Math.floor(Math.random() * 999999999); + } + + delete this.ensureDefault; +}; + +SWFUpload.prototype.loadFlash = function () { + if (this.settings.button_placeholder_id !== "") { + this.replaceWithFlash(); + } else { + this.appendFlash(); + } +}; + +// Private: appendFlash gets the HTML tag for the Flash +// It then appends the flash to the body +SWFUpload.prototype.appendFlash = function () { + var targetElement, container; + + // Make sure an element with the ID we are going to use doesn't already exist + if (document.getElementById(this.movieName) !== null) { + throw "ID " + this.movieName + " is already in use. The Flash Object could not be added"; + } + + // Get the body tag where we will be adding the flash movie + targetElement = document.getElementsByTagName("body")[0]; + + if (targetElement == undefined) { + throw "Could not find the 'body' element."; + } + + // Append the container and load the flash + container = document.createElement("div"); + container.style.width = "1px"; + container.style.height = "1px"; + container.style.overflow = "hidden"; + + targetElement.appendChild(container); + container.innerHTML = this.getFlashHTML(); // Using innerHTML is non-standard but the only sensible way to dynamically add Flash in IE (and maybe other browsers) +}; + +// Private: replaceWithFlash replaces the button_placeholder element with the flash movie. +SWFUpload.prototype.replaceWithFlash = function () { + var targetElement, tempParent; + + // Make sure an element with the ID we are going to use doesn't already exist + if (document.getElementById(this.movieName) !== null) { + throw "ID " + this.movieName + " is already in use. The Flash Object could not be added"; + } + + // Get the element where we will be placing the flash movie + targetElement = document.getElementById(this.settings.button_placeholder_id); + + if (targetElement == undefined) { + throw "Could not find the placeholder element."; + } + + // Append the container and load the flash + tempParent = document.createElement("div"); + tempParent.innerHTML = this.getFlashHTML(); // Using innerHTML is non-standard but the only sensible way to dynamically add Flash in IE (and maybe other browsers) + targetElement.parentNode.replaceChild(tempParent.firstChild, targetElement); + +}; + +// Private: getFlashHTML generates the object tag needed to embed the flash in to the document +SWFUpload.prototype.getFlashHTML = function () { + var transparent = this.settings.button_image_url === "" ? true : false; + + // Flash Satay object syntax: http://www.alistapart.com/articles/flashsatay + return ['', + '', + '', + '', + '', + '', + '', + ''].join(""); +}; + +// Private: getFlashVars builds the parameter string that will be passed +// to flash in the flashvars param. +SWFUpload.prototype.getFlashVars = function () { + // Build a string from the post param object + var paramString = this.buildParamString(); + + // Build the parameter string + return ["movieName=", encodeURIComponent(this.movieName), + "&uploadURL=", encodeURIComponent(this.settings.upload_url), + "&useQueryString=", encodeURIComponent(this.settings.use_query_string), + "&requeueOnError=", encodeURIComponent(this.settings.requeue_on_error), + "&params=", encodeURIComponent(paramString), + "&filePostName=", encodeURIComponent(this.settings.file_post_name), + "&fileTypes=", encodeURIComponent(this.settings.file_types), + "&fileTypesDescription=", encodeURIComponent(this.settings.file_types_description), + "&fileSizeLimit=", encodeURIComponent(this.settings.file_size_limit), + "&fileUploadLimit=", encodeURIComponent(this.settings.file_upload_limit), + "&fileQueueLimit=", encodeURIComponent(this.settings.file_queue_limit), + "&debugEnabled=", encodeURIComponent(this.settings.debug_enabled), + "&buttonImageURL=", encodeURIComponent(this.settings.button_image_url), + "&buttonWidth=", encodeURIComponent(this.settings.button_width), + "&buttonHeight=", encodeURIComponent(this.settings.button_height), + "&buttonText=", encodeURIComponent(this.settings.button_text), + "&buttonTextTopPadding=", encodeURIComponent(this.settings.button_text_top_padding), + "&buttonTextLeftPadding=", encodeURIComponent(this.settings.button_text_left_padding), + "&buttonTextStyle=", encodeURIComponent(this.settings.button_text_style), + "&buttonAction=", encodeURIComponent(this.settings.button_action), + "&buttonDisabled=", encodeURIComponent(this.settings.button_disabled) + ].join(""); +}; + +// Public: getMovieElement retrieves the DOM reference to the Flash element added by SWFUpload +// The element is cached after the first lookup +SWFUpload.prototype.getMovieElement = function () { + if (this.movieElement == undefined) { + this.movieElement = document.getElementById(this.movieName); + } + + if (this.movieElement === null) { + throw "Could not find Flash element"; + } + + return this.movieElement; +}; + +// Private: buildParamString takes the name/value pairs in the post_params setting object +// and joins them up in to a string formatted "name=value&name=value" +SWFUpload.prototype.buildParamString = function () { + var postParams = this.settings.post_params; + var paramStringPairs = []; + + if (typeof(postParams) === "object") { + for (var name in postParams) { + if (postParams.hasOwnProperty(name)) { + paramStringPairs.push(encodeURIComponent(name.toString()) + "=" + encodeURIComponent(postParams[name].toString())); + } + } + } + + return paramStringPairs.join("&"); +}; + +// Public: Used to remove a SWFUpload instance from the page. This method strives to remove +// all references to the SWF, and other objects so memory is properly freed. +// Returns true if everything was destroyed. Returns a false if a failure occurs leaving SWFUpload in an inconsistant state. +SWFUpload.prototype.destroy = function () { + try { + // Make sure Flash is done before we try to remove it + this.stopUpload(); + + // Remove the SWFUpload DOM nodes + var movieElement = null; + try { + movieElement = this.getMovieElement(); + } catch (ex) { + } + + if (movieElement != undefined && movieElement.parentNode != undefined && typeof movieElement.parentNode.removeChild === "function") { + var container = movieElement.parentNode; + if (container != undefined) { + container.removeChild(movieElement); + if (container.parentNode != undefined && typeof container.parentNode.removeChild === "function") { + container.parentNode.removeChild(container); + } + } + } + + // Destroy references + SWFUpload.instances[this.movieName] = null; + delete SWFUpload.instances[this.movieName]; + + delete this.movieElement; + delete this.settings; + delete this.customSettings; + delete this.eventQueue; + delete this.movieName; + + delete window[this.movieName]; + + return true; + } catch (ex1) { + return false; + } +}; + +// Public: displayDebugInfo prints out settings and configuration +// information about this SWFUpload instance. +// This function (and any references to it) can be deleted when placing +// SWFUpload in production. +SWFUpload.prototype.displayDebugInfo = function () { + this.debug( + [ + "---SWFUpload Instance Info---\n", + "Version: ", SWFUpload.version, "\n", + "Movie Name: ", this.movieName, "\n", + "Settings:\n", + "\t", "upload_url: ", this.settings.upload_url, "\n", + "\t", "flash_url: ", this.settings.flash_url, "\n", + "\t", "use_query_string: ", this.settings.use_query_string.toString(), "\n", + "\t", "file_post_name: ", this.settings.file_post_name, "\n", + "\t", "post_params: ", this.settings.post_params.toString(), "\n", + "\t", "file_types: ", this.settings.file_types, "\n", + "\t", "file_types_description: ", this.settings.file_types_description, "\n", + "\t", "file_size_limit: ", this.settings.file_size_limit, "\n", + "\t", "file_upload_limit: ", this.settings.file_upload_limit, "\n", + "\t", "file_queue_limit: ", this.settings.file_queue_limit, "\n", + "\t", "debug: ", this.settings.debug.toString(), "\n", + + "\t", "prevent_swf_caching: ", this.settings.prevent_swf_caching.toString(), "\n", + + "\t", "button_placeholder_id: ", this.settings.button_placeholder_id.toString(), "\n", + "\t", "button_image_url: ", this.settings.button_image_url.toString(), "\n", + "\t", "button_width: ", this.settings.button_width.toString(), "\n", + "\t", "button_height: ", this.settings.button_height.toString(), "\n", + "\t", "button_text: ", this.settings.button_text.toString(), "\n", + "\t", "button_text_style: ", this.settings.button_text_style.toString(), "\n", + "\t", "button_text_top_padding: ", this.settings.button_text_top_padding.toString(), "\n", + "\t", "button_text_left_padding: ", this.settings.button_text_left_padding.toString(), "\n", + "\t", "button_action: ", this.settings.button_action.toString(), "\n", + "\t", "button_disabled: ", this.settings.button_disabled.toString(), "\n", + + "\t", "custom_settings: ", this.settings.custom_settings.toString(), "\n", + "Event Handlers:\n", + "\t", "swfupload_loaded_handler assigned: ", (typeof this.settings.swfupload_loaded_handler === "function").toString(), "\n", + "\t", "file_dialog_start_handler assigned: ", (typeof this.settings.file_dialog_start_handler === "function").toString(), "\n", + "\t", "file_queued_handler assigned: ", (typeof this.settings.file_queued_handler === "function").toString(), "\n", + "\t", "file_queue_error_handler assigned: ", (typeof this.settings.file_queue_error_handler === "function").toString(), "\n", + "\t", "upload_start_handler assigned: ", (typeof this.settings.upload_start_handler === "function").toString(), "\n", + "\t", "upload_progress_handler assigned: ", (typeof this.settings.upload_progress_handler === "function").toString(), "\n", + "\t", "upload_error_handler assigned: ", (typeof this.settings.upload_error_handler === "function").toString(), "\n", + "\t", "upload_success_handler assigned: ", (typeof this.settings.upload_success_handler === "function").toString(), "\n", + "\t", "upload_complete_handler assigned: ", (typeof this.settings.upload_complete_handler === "function").toString(), "\n", + "\t", "debug_handler assigned: ", (typeof this.settings.debug_handler === "function").toString(), "\n" + ].join("") + ); +}; + +/* Note: addSetting and getSetting are no longer used by SWFUpload but are included + the maintain v2 API compatibility +*/ +// Public: (Deprecated) addSetting adds a setting value. If the value given is undefined or null then the default_value is used. +SWFUpload.prototype.addSetting = function (name, value, default_value) { + if (value == undefined) { + return (this.settings[name] = default_value); + } else { + return (this.settings[name] = value); + } +}; + +// Public: (Deprecated) getSetting gets a setting. Returns an empty string if the setting was not found. +SWFUpload.prototype.getSetting = function (name) { + if (this.settings[name] != undefined) { + return this.settings[name]; + } + + return ""; +}; + + + +// Private: callFlash handles function calls made to the Flash element. +// Calls are made with a setTimeout for some functions to work around +// bugs in the ExternalInterface library. +SWFUpload.prototype.callFlash = function (functionName, argumentArray) { + argumentArray = argumentArray || []; + + var movieElement = this.getMovieElement(); + var returnValue; + + if (typeof movieElement[functionName] === "function") { + // We have to go through all this if/else stuff because the Flash functions don't have apply() and only accept the exact number of arguments. + if (argumentArray.length === 0) { + returnValue = movieElement[functionName](); + } else if (argumentArray.length === 1) { + returnValue = movieElement[functionName](argumentArray[0]); + } else if (argumentArray.length === 2) { + returnValue = movieElement[functionName](argumentArray[0], argumentArray[1]); + } else if (argumentArray.length === 3) { + returnValue = movieElement[functionName](argumentArray[0], argumentArray[1], argumentArray[2]); + } else { + throw "Too many arguments"; + } + + // Unescape file post param values + if (returnValue != undefined && typeof returnValue.post === "object") { + returnValue = this.unescapeFilePostParams(returnValue); + } + + return returnValue; + } else { + throw "Invalid function name: " + functionName; + } +}; + + +/* ***************************** + -- Flash control methods -- + Your UI should use these + to operate SWFUpload + ***************************** */ + +// Public: selectFile causes a File Selection Dialog window to appear. This +// dialog only allows 1 file to be selected. WARNING: this function does not work in Flash Player 10 +SWFUpload.prototype.selectFile = function () { + this.callFlash("SelectFile"); +}; + +// Public: selectFiles causes a File Selection Dialog window to appear/ This +// dialog allows the user to select any number of files +// Flash Bug Warning: Flash limits the number of selectable files based on the combined length of the file names. +// If the selection name length is too long the dialog will fail in an unpredictable manner. There is no work-around +// for this bug. WARNING: this function does not work in Flash Player 10 +SWFUpload.prototype.selectFiles = function () { + this.callFlash("SelectFiles"); +}; + + +// Public: startUpload starts uploading the first file in the queue unless +// the optional parameter 'fileID' specifies the ID +SWFUpload.prototype.startUpload = function (fileID) { + this.callFlash("StartUpload", [fileID]); +}; + +/* Cancels a the file upload. You must specify a file_id */ +// Public: cancelUpload cancels any queued file. The fileID parameter +// must be specified. +SWFUpload.prototype.cancelUpload = function (fileID) { + this.callFlash("CancelUpload", [fileID]); +}; + +// Public: stopUpload stops the current upload and requeues the file at the beginning of the queue. +// If nothing is currently uploading then nothing happens. +SWFUpload.prototype.stopUpload = function () { + this.callFlash("StopUpload"); +}; + +/* ************************ + * Settings methods + * These methods change the SWFUpload settings. + * SWFUpload settings should not be changed directly on the settings object + * since many of the settings need to be passed to Flash in order to take + * effect. + * *********************** */ + +// Public: getStats gets the file statistics object. +SWFUpload.prototype.getStats = function () { + return this.callFlash("GetStats"); +}; + +// Public: setStats changes the SWFUpload statistics. You shouldn't need to +// change the statistics but you can. Changing the statistics does not +// affect SWFUpload accept for the successful_uploads count which is used +// by the upload_limit setting to determine how many files the user may upload. +SWFUpload.prototype.setStats = function (statsObject) { + this.callFlash("SetStats", [statsObject]); +}; + +// Public: getFile retrieves a File object by ID or Index. If the file is +// not found then 'null' is returned. +SWFUpload.prototype.getFile = function (fileID) { + if (typeof(fileID) === "number") { + return this.callFlash("GetFileByIndex", [fileID]); + } else { + return this.callFlash("GetFile", [fileID]); + } +}; + +// Public: addFileParam sets a name/value pair that will be posted with the +// file specified by the Files ID. If the name already exists then the +// exiting value will be overwritten. +SWFUpload.prototype.addFileParam = function (fileID, name, value) { + return this.callFlash("AddFileParam", [fileID, name, value]); +}; + +// Public: removeFileParam removes a previously set (by addFileParam) name/value +// pair from the specified file. +SWFUpload.prototype.removeFileParam = function (fileID, name) { + this.callFlash("RemoveFileParam", [fileID, name]); +}; + +// Public: setUploadUrl changes the upload_url setting. +SWFUpload.prototype.setUploadURL = function (url) { + this.settings.upload_url = url.toString(); + this.callFlash("SetUploadURL", [url]); +}; + +// Public: setPostParams changes the post_params setting +SWFUpload.prototype.setPostParams = function (paramsObject) { + this.settings.post_params = paramsObject; + this.callFlash("SetPostParams", [paramsObject]); +}; + +// Public: addPostParam adds post name/value pair. Each name can have only one value. +SWFUpload.prototype.addPostParam = function (name, value) { + this.settings.post_params[name] = value; + this.callFlash("SetPostParams", [this.settings.post_params]); +}; + +// Public: removePostParam deletes post name/value pair. +SWFUpload.prototype.removePostParam = function (name) { + delete this.settings.post_params[name]; + this.callFlash("SetPostParams", [this.settings.post_params]); +}; + +// Public: setFileTypes changes the file_types setting and the file_types_description setting +SWFUpload.prototype.setFileTypes = function (types, description) { + this.settings.file_types = types; + this.settings.file_types_description = description; + this.callFlash("SetFileTypes", [types, description]); +}; + +// Public: setFileSizeLimit changes the file_size_limit setting +SWFUpload.prototype.setFileSizeLimit = function (fileSizeLimit) { + this.settings.file_size_limit = fileSizeLimit; + this.callFlash("SetFileSizeLimit", [fileSizeLimit]); +}; + +// Public: setFileUploadLimit changes the file_upload_limit setting +SWFUpload.prototype.setFileUploadLimit = function (fileUploadLimit) { + this.settings.file_upload_limit = fileUploadLimit; + this.callFlash("SetFileUploadLimit", [fileUploadLimit]); +}; + +// Public: setFileQueueLimit changes the file_queue_limit setting +SWFUpload.prototype.setFileQueueLimit = function (fileQueueLimit) { + this.settings.file_queue_limit = fileQueueLimit; + this.callFlash("SetFileQueueLimit", [fileQueueLimit]); +}; + +// Public: setFilePostName changes the file_post_name setting +SWFUpload.prototype.setFilePostName = function (filePostName) { + this.settings.file_post_name = filePostName; + this.callFlash("SetFilePostName", [filePostName]); +}; + +// Public: setUseQueryString changes the use_query_string setting +SWFUpload.prototype.setUseQueryString = function (useQueryString) { + this.settings.use_query_string = useQueryString; + this.callFlash("SetUseQueryString", [useQueryString]); +}; + +// Public: setRequeueOnError changes the requeue_on_error setting +SWFUpload.prototype.setRequeueOnError = function (requeueOnError) { + this.settings.requeue_on_error = requeueOnError; + this.callFlash("SetRequeueOnError", [requeueOnError]); +}; + +// Public: setDebugEnabled changes the debug_enabled setting +SWFUpload.prototype.setDebugEnabled = function (debugEnabled) { + this.settings.debug_enabled = debugEnabled; + this.callFlash("SetDebugEnabled", [debugEnabled]); +}; + +// Public: setButtonImageURL loads a button image sprite +SWFUpload.prototype.setButtonImageURL = function (buttonImageURL) { + if (buttonImageURL == undefined) { + buttonImageURL = ""; + } + + this.settings.button_image_url = buttonImageURL; + this.callFlash("SetButtonImageURL", [buttonImageURL]); +}; + +// Public: setButtonDimensions resizes the Flash Movie and button +SWFUpload.prototype.setButtonDimensions = function (width, height) { + this.settings.button_width = width; + this.settings.button_height = height; + + var movie = this.getMovieElement(); + if (movie != undefined) { + movie.style.width = width + "px"; + movie.style.height = height + "px"; + } + + this.callFlash("SetButtonDimensions", [width, height]); +}; +// Public: setButtonText Changes the text overlaid on the button +SWFUpload.prototype.setButtonText = function (html) { + this.settings.button_text = html; + this.callFlash("SetButtonText", [html]); +}; +// Public: setButtonTextPadding changes the top and left padding of the text overlay +SWFUpload.prototype.setButtonTextPadding = function (left, top) { + this.settings.button_text_top_padding = top; + this.settings.button_text_left_padding = left; + this.callFlash("SetButtonTextPadding", [left, top]); +}; + +// Public: setButtonTextStyle changes the CSS used to style the HTML/Text overlaid on the button +SWFUpload.prototype.setButtonTextStyle = function (css) { + this.settings.button_text_style = css; + this.callFlash("SetButtonTextStyle", [css]); +}; +// Public: setButtonDisabled disables/enables the button +SWFUpload.prototype.setButtonDisabled = function (isDisabled) { + this.settings.button_disabled = isDisabled; + this.callFlash("SetButtonDisabled", [isDisabled]); +}; +// Public: setButtonAction sets the action that occurs when the button is clicked +SWFUpload.prototype.setButtonAction = function (buttonAction) { + this.settings.button_action = buttonAction; + this.callFlash("SetButtonAction", [buttonAction]); +}; + +/* ******************************* + Flash Event Interfaces + These functions are used by Flash to trigger the various + events. + + All these functions a Private. + + Because the ExternalInterface library is buggy the event calls + are added to a queue and the queue then executed by a setTimeout. + This ensures that events are executed in a determinate order and that + the ExternalInterface bugs are avoided. +******************************* */ + +SWFUpload.prototype.queueEvent = function (handlerName, argumentArray) { + // Warning: Don't call this.debug inside here or you'll create an infinite loop + + if (argumentArray == undefined) { + argumentArray = []; + } else if (!(argumentArray instanceof Array)) { + argumentArray = [argumentArray]; + } + + var self = this; + if (typeof this.settings[handlerName] === "function") { + // Queue the event + this.eventQueue.push(function () { + this.settings[handlerName].apply(this, argumentArray); + }); + + // Execute the next queued event + setTimeout(function () { + self.executeNextEvent(); + }, 0); + + } else if (this.settings[handlerName] !== null) { + throw "Event handler " + handlerName + " is unknown or is not a function"; + } +}; + +// Private: Causes the next event in the queue to be executed. Since events are queued using a setTimeout +// we must queue them in order to garentee that they are executed in order. +SWFUpload.prototype.executeNextEvent = function () { + // Warning: Don't call this.debug inside here or you'll create an infinite loop + + var f = this.eventQueue ? this.eventQueue.shift() : null; + if (typeof(f) === "function") { + f.apply(this); + } +}; + +// Private: unescapeFileParams is part of a workaround for a flash bug where objects passed through ExternalInterface cannot have +// properties that contain characters that are not valid for JavaScript identifiers. To work around this +// the Flash Component escapes the parameter names and we must unescape again before passing them along. +SWFUpload.prototype.unescapeFilePostParams = function (file) { + var reg = /[$]([0-9a-f]{4})/i; + var unescapedPost = {}; + var uk; + + if (file != undefined) { + for (var k in file.post) { + if (file.post.hasOwnProperty(k)) { + uk = k; + var match; + while ((match = reg.exec(uk)) !== null) { + uk = uk.replace(match[0], String.fromCharCode(parseInt("0x" + match[1], 16))); + } + unescapedPost[uk] = file.post[k]; + } + } + + file.post = unescapedPost; + } + + return file; +}; + +SWFUpload.prototype.flashReady = function () { + // Check that the movie element is loaded correctly with its ExternalInterface methods defined + var movieElement = this.getMovieElement(); + if (typeof movieElement.StartUpload !== "function") { + throw "ExternalInterface methods failed to initialize."; + } + + // Fix IE Flash/Form bug + if (window[this.movieName] == undefined) { + window[this.movieName] = movieElement; + } + + this.queueEvent("swfupload_loaded_handler"); +}; + + +/* This is a chance to do something before the browse window opens */ +SWFUpload.prototype.fileDialogStart = function () { + this.queueEvent("file_dialog_start_handler"); +}; + + +/* Called when a file is successfully added to the queue. */ +SWFUpload.prototype.fileQueued = function (file) { + file = this.unescapeFilePostParams(file); + this.queueEvent("file_queued_handler", file); +}; + + +/* Handle errors that occur when an attempt to queue a file fails. */ +SWFUpload.prototype.fileQueueError = function (file, errorCode, message) { + file = this.unescapeFilePostParams(file); + this.queueEvent("file_queue_error_handler", [file, errorCode, message]); +}; + +/* Called after the file dialog has closed and the selected files have been queued. + You could call startUpload here if you want the queued files to begin uploading immediately. */ +SWFUpload.prototype.fileDialogComplete = function (numFilesSelected, numFilesQueued) { + this.queueEvent("file_dialog_complete_handler", [numFilesSelected, numFilesQueued]); +}; + +SWFUpload.prototype.uploadStart = function (file) { + file = this.unescapeFilePostParams(file); + this.queueEvent("return_upload_start_handler", file); +}; + +SWFUpload.prototype.returnUploadStart = function (file) { + var returnValue; + if (typeof this.settings.upload_start_handler === "function") { + file = this.unescapeFilePostParams(file); + returnValue = this.settings.upload_start_handler.call(this, file); + } else if (this.settings.upload_start_handler != undefined) { + throw "upload_start_handler must be a function"; + } + + // Convert undefined to true so if nothing is returned from the upload_start_handler it is + // interpretted as 'true'. + if (returnValue === undefined) { + returnValue = true; + } + + returnValue = !!returnValue; + + this.callFlash("ReturnUploadStart", [returnValue]); +}; + + + +SWFUpload.prototype.uploadProgress = function (file, bytesComplete, bytesTotal) { + file = this.unescapeFilePostParams(file); + this.queueEvent("upload_progress_handler", [file, bytesComplete, bytesTotal]); +}; + +SWFUpload.prototype.uploadError = function (file, errorCode, message) { + file = this.unescapeFilePostParams(file); + this.queueEvent("upload_error_handler", [file, errorCode, message]); +}; + +SWFUpload.prototype.uploadSuccess = function (file, serverData) { + file = this.unescapeFilePostParams(file); + this.queueEvent("upload_success_handler", [file, serverData]); +}; + +SWFUpload.prototype.uploadComplete = function (file) { + file = this.unescapeFilePostParams(file); + this.queueEvent("upload_complete_handler", file); +}; + +/* Called by SWFUpload JavaScript and Flash functions when debug is enabled. By default it writes messages to the + internal debug console. You can override this event and have messages written where you want. */ +SWFUpload.prototype.debug = function (message) { + this.queueEvent("debug_handler", message); +}; + + +/* ********************************** + Debug Console + The debug console is a self contained, in page location + for debug message to be sent. The Debug Console adds + itself to the body if necessary. + + The console is automatically scrolled as messages appear. + + If you are using your own debug handler or when you deploy to production and + have debug disabled you can remove these functions to reduce the file size + and complexity. +********************************** */ + +// Private: debugMessage is the default debug_handler. If you want to print debug messages +// call the debug() function. When overriding the function your own function should +// check to see if the debug setting is true before outputting debug information. +SWFUpload.prototype.debugMessage = function (message) { + if (this.settings.debug) { + var exceptionMessage, exceptionValues = []; + + // Check for an exception object and print it nicely + if (typeof message === "object" && typeof message.name === "string" && typeof message.message === "string") { + for (var key in message) { + if (message.hasOwnProperty(key)) { + exceptionValues.push(key + ": " + message[key]); + } + } + exceptionMessage = exceptionValues.join("\n") || ""; + exceptionValues = exceptionMessage.split("\n"); + exceptionMessage = "EXCEPTION: " + exceptionValues.join("\nEXCEPTION: "); + SWFUpload.Console.writeLine(exceptionMessage); + } else { + SWFUpload.Console.writeLine(message); + } + } +}; + +SWFUpload.Console = {}; +SWFUpload.Console.writeLine = function (message) { + var console, documentForm; + + try { + console = document.getElementById("SWFUpload_Console"); + + if (!console) { + documentForm = document.createElement("form"); + document.getElementsByTagName("body")[0].appendChild(documentForm); + + console = document.createElement("textarea"); + console.id = "SWFUpload_Console"; + console.style.fontFamily = "monospace"; + console.setAttribute("wrap", "off"); + console.wrap = "off"; + console.style.overflow = "auto"; + console.style.width = "700px"; + console.style.height = "350px"; + console.style.margin = "5px"; + documentForm.appendChild(console); + } + + console.value += message + "\n"; + + console.scrollTop = console.scrollHeight - console.clientHeight; + } catch (ex) { + alert("Exception: " + ex.name + " Message: " + ex.message); + } +}; diff --git a/modules/editor/tpl/js/uploader.js b/modules/editor/tpl/js/uploader.js index 2248f5981..4a1af50e0 100755 --- a/modules/editor/tpl/js/uploader.js +++ b/modules/editor/tpl/js/uploader.js @@ -1,163 +1,141 @@ /** * @author zero (zero@nzeo.com) - * @version 0.1 + * @version 0.1.1 * @brief 파일 업로드 관련 - * - ***************************************************************************************************************************** - * 제로보드XE의 게시물 파일업로드 컴포넌트는 "mmSWFUpload 1.0: Flash upload dialog - http://swfupload.mammon.se/" 를 사용합니다. - * - SWFUpload is (c) 2006 Lars Huring and Mammon Media and is released under the MIT License:http://www.opensource.org/licenses/mit-license.php - ***************************************************************************************************************************** - - * 감사합니다. **/ -var uploading_file = false; -var uploaded_files = new Array(); +var uploadedFiles = new Array(); +var uploaderSettings = new Array(); /** * 업로드를 하기 위한 준비 시작 * 이 함수는 editor.html 에서 파일 업로드 가능할 경우 호출됨 **/ // window.load 이벤트일 경우 && 문서 번호가 가상의 번호가 아니면 기존에 저장되어 있을지도 모르는 파일 목록을 가져옴 -function editor_upload_init(editor_sequence, el, inserted_files_count) { - xAddEventListener(window,'load',function() { editor_upload_start(editor_sequence, el, inserted_files_count);} ); -} - -function editor_upload_get_target_srl(editor_sequence) { - return editorRelKeys[editor_sequence]["primary"].value; -} - -function editor_upload_get_uploader_name(editor_sequence) { - return "swf_uploader_"+editor_sequence; - +function editorUploadInit(obj) { + if(typeof(obj["editorSequence"])=="undefined") return; + if(typeof(obj["sessionName"])=="undefined") obj["sessionName"]= "PHPSESSID"; + if(typeof(obj["allowedFileSize"])=="undefined") obj["allowdFileSize"]= "2MB"; + if(typeof(obj["allowedFileTypes"])=="undefined") obj["allowedFileTypes"]= "*.*"; + if(typeof(obj["allowedFileTypesDescription"])=="undefined") obj["allowedFileTypesDescription"]= "All Files"; + if(typeof(obj["replaceButtonID"])=="undefined") obj["replaceButtonID"] = "swfUploadButton"+obj["editorSequence"]; + if(typeof(obj["insertedFiles"])=="undefined") obj["insertedFiles"] = 0; + xAddEventListener(window,"load",function() { XEUploaderStart(obj) }); } // 파일 업로드를 위한 기본 준비를 함 -function editor_upload_start(editor_sequence, fo_obj, inserted_files_count) { - if(typeof(inserted_files_count)=='undefined' || !inserted_files_count) inserted_files_count = 0; - else inserted_files_count = parseInt(inserted_files_count, 10); - - // 캐시 삭제 +function XEUploaderStart(obj) { try { document.execCommand('BackgroundImageCache',false,true); } catch(e) { } - // 임시 iframe을 생성 (공통으로 사용) - if(!xGetElementById('tmp_upload_iframe')) { - if(xIE4Up) { - window.document.body.insertAdjacentHTML("afterEnd", ""); - } else { - var obj_iframe = xCreateElement('IFRAME'); - obj_iframe.name = obj_iframe.id = 'tmp_upload_iframe'; - obj_iframe.style.display = 'none'; - obj_iframe.style.width = '1px'; - obj_iframe.style.height = '1px'; - obj_iframe.style.position = 'absolute'; - obj_iframe.style.top = '-10px'; - obj_iframe.style.left = '-10px'; - window.document.body.appendChild(obj_iframe); - } - } + var btnObj = xGetElementById(obj["replaceButtonID"]); + var btnWidth = xWidth(btnObj); + var btnHeight = xHeight(btnObj)*2; + btnObj.style.position = "relative"; - // 첨부파일 목록을 출력하는 select element 구함 - var field_obj = xGetElementById("uploaded_file_list_"+editor_sequence); - if(!field_obj) return; + var dummy = xCreateElement("span"); + dummy.id = "dummy"+obj["replaceButtonID"]; + btnObj.appendChild(dummy); - // 에디터를 감싸는 form을 구해 submit target을 임시 iframe으로 변경 - if(!fo_obj) fo_obj = editorGetForm(editor_sequence); - fo_obj.target = 'tmp_upload_iframe'; + var settings = { + flash_url : request_uri+"modules/editor/tpl/images/SWFUpload.swf", + upload_url: request_uri, + post_params: { + "mid" : current_url.getQuery("mid"), + "act" : "procFileUpload", + "editor_sequence" : obj["editorSequence"] + }, + file_size_limit : obj["allowedFileSize"], + file_types : obj["allowedFileTypes"], + file_types_description : obj["allowedFileTypesDescription"], + file_upload_limit : 0, + file_queue_limit : 0, + custom_settings : { + progressTarget : null, + cancelButtonId : null + }, + debug: false, - // SWF uploader 생성 - var uploader_name = editor_upload_get_uploader_name(editor_sequence); - var embed_html = ""; + // Button settings + button_placeholder_id: dummy.id, + button_text: null, + button_image_url: "", + button_width: btnWidth, + button_height: btnHeight, + button_text_style: null, + button_text_left_padding: 0, + button_text_top_padding: 0, - // 업로드와 관련된 변수 설정 (이 변수들이 그대로 zbxe에 전달됨) - var flashVars = ''+ - 'uploadProgressCallback=editor_upload_progress'+ - '&uploadFileErrorCallback=editor_upload_error_handle'+ - '&allowedFiletypesDescription='+uploader_setting["allowed_filetypes_description"]+ - '&autoUpload=true&allowedFiletypes='+uploader_setting["allowed_filetypes"]+ - '&maximumFilesize='+uploader_setting["allowed_filesize"]+ - '&uploadQueueCompleteCallback=editor_display_uploaded_file'+ - '&uploadScript='+escape( request_uri+'?mid='+current_url.getQuery('mid')+ - '&act=procFileUpload'+ - '&editor_sequence='+editor_sequence+ - '&'+xe_session_name+'='+xGetCookie(xe_session_name) - ); + // The event handler functions are defined in handlers.js + file_queued_handler : fileQueued, + file_queue_error_handler : fileQueueError, + file_dialog_complete_handler : fileDialogComplete, + upload_start_handler : uploadStart, + upload_progress_handler : uploadProgress, + upload_error_handler : uploadError, + upload_success_handler : uploadSuccess, + upload_complete_handler : uploadComplete, + queue_complete_handler :queueComplete + }; + settings["post_params"][obj["sessionName"]] = xGetCookie(obj["sessionName"]); + settings["editorSequence"] = obj["editorSequence"]; + settings["uploadTargetSrl"] = editorRelKeys[obj["editorSequence"]]["primary"].value; + settings["fileListAreaID"] = obj["fileListAreaID"]; + settings["previewAreaID"] = obj["previewAreaID"]; + settings["uploaderStatusID"] = obj["uploaderStatusID"]; - // 객체 생성 코드 - if(navigator.plugins&&navigator.mimeTypes&&navigator.mimeTypes.length) { - embed_html = ''; - } else { - embed_html = ''; - } + uploaderSettings[obj["editorSequence"]] = settings; - // div dummy 객체를 만들고 SWFUploader 코드를 추가하여 객체 생성 - var dummy = xCreateElement("div"); - dummy.style.width = "1px"; - dummy.style.height = "1px"; - dummy.style.position="absolute"; - dummy.style.top="0px"; - dummy.style.left="0px"; - window.document.body.appendChild(dummy); - xInnerHtml(dummy, embed_html); + var swfu = new SWFUpload(settings); + var swfObj = xGetElementById(swfu.movieName); + if(!swfObj) return; - /** - * upload_target_srl값이 실제 문서 번호일 경우 이미 등록되 있을지도 모르는 첨부파일 목록을 로드 - * procDeleteFile에 file_srl을 보내주지 않으면 삭제시도는 없이 목록만 갱신할 수 있음 - **/ - if(inserted_files_count>0) editor_display_uploaded_file(editor_sequence); + swfObj.style.display = "block"; + swfObj.style.cursor = "pointer"; + swfObj.style.position = "absolute"; + swfObj.style.left = 0; + swfObj.style.top = "-3px"; + swfObj.style.width = btnWidth+"px"; + swfObj.style.height = btnHeight+"px"; + + reloadFileList(settings); } -// 파일 업로드 에러 핸들링 -function editor_upload_error_handle(errcode,file,msg) { - switch(errcode) { - case -10 : - alert("- Error Code: HTTP Error\n- File name: "+file.name+"\n- Message: "+msg); +function fileQueued(file) { +} + +function fileQueueError(file, errorCode, message) { + switch(errorCode) { + case SWFUpload.QUEUE_ERROR.QUEUE_LIMIT_EXCEEDED : + alert("You have attempted to queue too many files.\n" + (message === 0 ? "You have reached the upload limit." : "You may select " + (message > 1 ? "up to " + message + " files." : "one file."))); break; - case -20 : - alert("- Error Code: No upload script\n- File name: "+file.name+"\n- Message: "+msg); + case SWFUpload.QUEUE_ERROR.FILE_EXCEEDS_SIZE_LIMIT: + alert("Error Code: File too big, File name: " + file.name + ", File size: " + file.size + ", Message: " + message); break; - case -30 : - alert("- Error Code: IO Error\n- File name: "+file.name+"\n- Message: "+msg); + case SWFUpload.QUEUE_ERROR.ZERO_BYTE_FILE: + alert("Error Code: Zero byte file, File name: " + file.name + ", File size: " + file.size + ", Message: " + message); break; - case -40 : - alert("- Error Code: Security Error\n- File name: "+file.name+"\n- Message: "+msg); + case SWFUpload.QUEUE_ERROR.INVALID_FILETYPE: + alert("Error Code: Invalid File Type, File name: " + file.name + ", File size: " + file.size + ", Message: " + message); break; - case -50 : - alert("- Error Code: Filesize exceeds limit\n- File name: "+file.name+"\n- File size: "+file.size+"\n- Message: "+msg); + default: + alert("Error Code: " + errorCode + ", File name: " + file.name + ", File size: " + file.size + ", Message: " + message); break; } } -/** - * 파일 업로드 관련 함수들 - **/ - -// 파일 업로드 -var _prev_editor_sequence; ///< 진행 상태를 표시하기 위해 바로 이전의 에디터 sequence값을 가지고 있음 -function editor_upload_file(editor_sequence) { - // 업로더 객체를 구함 - var uploader_name = editor_upload_get_uploader_name(editor_sequence); - var swf_uploader = xGetElementById(uploader_name); - +function fileDialogComplete(numFilesSelected, numFilesQueued) { try { - swf_uploader.browse(); - _prev_editor_sequence = editor_sequence; - } catch(e) { + this.startUpload(); + } catch (ex) { } - } -// 업로드 진행상태 표시 -var _progress_start = false; -function editor_upload_progress(file, bytesLoaded) { - var obj = xGetElementById('uploaded_file_list_'+_prev_editor_sequence); - if(!_progress_start) { - while(obj.options.length) { - obj.remove(0); - } - _progress_start = true; - } +function uploadStart(file) { +} - var percent = Math.ceil((bytesLoaded / file.size) * 100); +function uploadProgress(file, bytesLoaded, bytesTotal) { + var obj = xGetElementById(this.settings["fileListAreaID"]); + + var percent = Math.ceil((bytesLoaded / bytesTotal) * 100); var filename = file.name; if(filename.length>20) filename = filename.substr(0,20)+'...'; @@ -170,67 +148,126 @@ function editor_upload_progress(file, bytesLoaded) { } } -// upload_target_srl 에 등록된 파일 표시 -function editor_display_uploaded_file(editor_sequence) { - if(typeof(editor_sequence)=='undefined'||!editor_sequence) editor_sequence = _prev_editor_sequence; - if(!editor_sequence) return; - - // 이미 등록된 전체 파일 목록을 구해옴 - var url = request_uri + "?act=procFileDelete&editor_sequence="+editor_sequence+"&mid="+current_url.getQuery('mid'); - - // iframe에 url을 보내버림 - var iframe_obj = xGetElementById('tmp_upload_iframe'); - if(!iframe_obj) return; - iframe_obj.contentWindow.document.location.href=url; +function uploadSuccess(file, serverData) { } - -// 업로드된 파일 목록 비움 (단순히 select 객체의 내용을 지우고 미리보기를 제거함) -function editor_upload_clear_list(editor_sequence, upload_target_srl) { - if(!upload_target_srl || upload_target_srl<1) return; - editorRelKeys[editor_sequence]["primary"].value = upload_target_srl; - - var obj = xGetElementById('uploaded_file_list_'+editor_sequence); - while(obj.options.length) { - obj.remove(0); +function uploadError(file, errorCode, message) { + try { + switch (errorCode) { + case SWFUpload.UPLOAD_ERROR.HTTP_ERROR: + alert("Error Code: HTTP Error, File name: " + file.name + ", Message: " + message); + break; + case SWFUpload.UPLOAD_ERROR.UPLOAD_FAILED: + alert("Error Code: Upload Failed, File name: " + file.name + ", File size: " + file.size + ", Message: " + message); + break; + case SWFUpload.UPLOAD_ERROR.IO_ERROR: + alert("Error Code: IO Error, File name: " + file.name + ", Message: " + message); + break; + case SWFUpload.UPLOAD_ERROR.SECURITY_ERROR: + alert("Error Code: Security Error, File name: " + file.name + ", Message: " + message); + break; + case SWFUpload.UPLOAD_ERROR.UPLOAD_LIMIT_EXCEEDED: + alert("Error Code: Upload Limit Exceeded, File name: " + file.name + ", File size: " + file.size + ", Message: " + message); + break; + case SWFUpload.UPLOAD_ERROR.FILE_VALIDATION_FAILED: + alert("Error Code: File Validation Failed, File name: " + file.name + ", File size: " + file.size + ", Message: " + message); + break; + case SWFUpload.UPLOAD_ERROR.FILE_CANCELLED: + // If there aren't any files left (they were all cancelled) disable the cancel button + if (this.getStats().files_queued === 0) { + document.getElementById(this.customSettings.cancelButtonId).disabled = true; + } + break; + case SWFUpload.UPLOAD_ERROR.UPLOAD_STOPPED: + break; + default: + alert("Error Code: " + errorCode + ", File name: " + file.name + ", File size: " + file.size + ", Message: " + message); + break; + } + } catch (ex) { + alert(ex); } - var preview_obj = xGetElementById('preview_uploaded_'+editor_sequence); - xInnerHtml(preview_obj,'') } -// 업로드된 파일 정보를 select 목록에 추가 -function editor_insert_uploaded_file(editor_sequence, file_srl, filename, file_size, disp_file_size, uploaded_filename, sid) { - var obj = xGetElementById('uploaded_file_list_'+editor_sequence); - var text = disp_file_size+' - '+filename; - var opt_obj = new Option(text, file_srl, true, true); - obj.options[obj.options.length] = opt_obj; - - var file_obj = {file_srl:file_srl, filename:filename, file_size:file_size, uploaded_filename:uploaded_filename, sid:sid} - uploaded_files[file_srl] = file_obj; - - editor_preview(obj, editor_sequence); - _progress_start = false; +function uploadComplete(file) { + if(this.getStats().files_queued === 0 ) { + var fileListAreaID = this.settings["fileListAreaID"]; + var uploadTargetSrl = this.settings["uploadTargetSrl"]; + reloadFileList(this.settings); + } else { + try { + this.startUpload(); + } catch(e) { + } + } } -// 파일 목록창에서 클릭 되었을 경우 미리 보기 -function editor_preview(sel_obj, editor_sequence) { - var preview_obj = xGetElementById('preview_uploaded_'+editor_sequence); - if(!sel_obj.options.length) { - xInnerHtml(preview_obj, ''); - return; +function queueComplete(numFilesUploaded) { +} + +function reloadFileList(settings) { + var params = new Array(); + params["file_list_area_id"] = settings["fileListAreaID"]; + params["editor_sequence"] = settings["editorSequence"]; + var response_tags = new Array("error","message","files","upload_status","upload_target_srl","editor_sequence"); + exec_xml("file","getFileList", params, completeReloadFileList, response_tags, settings); +} + +function completeReloadFileList(ret_obj, response_tags, settings) { + var upload_target_srl = ret_obj['upload_target_srl']; + var editor_sequence = ret_obj['editor_sequence']; + var upload_status = ret_obj['upload_status']; + var files = ret_obj['files']; + var file_list_area_id = settings["fileListAreaID"]; + var listObj = xGetElementById(file_list_area_id); + while(listObj.options.length) { + listObj.remove(0); } - var file_srl = sel_obj.options[sel_obj.selectedIndex].value; - var obj = uploaded_files[file_srl]; - if(typeof(obj)=='undefined'||!obj) return; - var uploaded_filename = obj.uploaded_filename; - - if(!uploaded_filename) { - xInnerHtml(preview_obj, ''); - return; + var cur_upload_target_srl = editorRelKeys[editor_sequence]["primary"].value; + if(!cur_upload_target_srl) { + editorRelKeys[editor_sequence]["primary"].value = upload_target_srl; + settings["uploadTargetSrl"] = upload_target_srl; } + var statusObj = xGetElementById(settings["uploaderStatusID"]); + if(statusObj) xInnerHtml(statusObj, upload_status); + + var previewObj = xGetElementById(settings["previewAreaID"]); + if(previewObj) xInnerHtml(previewObj,""); + + if(files) { + var item = files['item']; + if(item.length<1) item = new Array(item); + if(item.length) { + for(var i=0;i"; } - xInnerHtml(preview_obj, html); + xInnerHtml(previewAreaID, html); } -// 업로드된 파일 삭제 -function editor_remove_file(editor_sequence) { - var obj = xGetElementById('uploaded_file_list_'+editor_sequence); - if(obj.options.length<1) return; +function removeUploadedFile(editorSequence) { + var settings = uploaderSettings[editorSequence]; + var fileListAreaID = settings["fileListAreaID"]; + var fileListObj = xGetElementById(fileListAreaID); + if(!fileListObj) return; - // 삭제하려는 파일의 정보를 챙김;; - var fo_obj = obj; - while(fo_obj.nodeName != 'FORM') { fo_obj = fo_obj.parentNode; } - var mid = fo_obj.mid.value; + if(fileListObj.selectedIndex<0) return; - // 빈 iframe 구함 - var iframe_obj = xGetElementById('tmp_upload_iframe'); + var file_srl = fileListObj.options[fileListObj.selectedIndex].value; + + if(!file_srl) return; + + var params = new Array(); + params["file_srl"] = file_srl; + params["editor_sequence"] = editorSequence; + var response_tags = new Array("error","message"); + exec_xml("file","procFileDelete", params, function() { reloadFileList(settings); } ); +} + +function insertUploadedFile(editorSequence) { + var settings = uploaderSettings[editorSequence]; + var fileListAreaID = settings["fileListAreaID"]; + var fileListObj = xGetElementById(fileListAreaID); + if(!fileListObj) return; + + if(typeof(editorMode)!='undefined' && editorMode[editorSequence]=='html') return; + + var iframe_obj = editorGetIFrame(editorSequence); if(!iframe_obj) return; - // upload_target_srl이 가상 번호일 경우 아무 동작 하지 않음 - var upload_target_srl = editorRelKeys[editor_sequence]["primary"].value; - if(upload_target_srl<1) return; - - for(var i=0;i"; - editorReplaceHTML(iframe_obj, text); + if(/\.(jpg|jpeg|png|gif)$/i.test(file.download_url)) { + var text = "\""+file.source_filename+"\""; // 이미지외의 경우는 multimedia_link 컴포넌트 연결 } else { - var text = "\"\""; - editorReplaceHTML(iframe_obj, text); + var text = "\"\""; } - // binary파일의 경우 url_link 컴포넌트 연결 + // binary파일의 경우 url_link 컴포넌트 연결 } else { - var mid = fo_obj.mid.value; - var url = "./?module=file&act=procFileDownload&file_srl="+file_srl+"&sid="+sid; - var text = ""+filename+"\n"; - editorReplaceHTML(iframe_obj, text); + var text = ""+file.source_filename+"\n"; } + if(text) editorReplaceHTML(iframe_obj, text); } } diff --git a/modules/file/conf/module.xml b/modules/file/conf/module.xml index 654b422ea..0c1f97186 100644 --- a/modules/file/conf/module.xml +++ b/modules/file/conf/module.xml @@ -5,6 +5,8 @@ + + diff --git a/modules/file/file.admin.view.php b/modules/file/file.admin.view.php index eccfa0ff2..c883a3e57 100644 --- a/modules/file/file.admin.view.php +++ b/modules/file/file.admin.view.php @@ -85,8 +85,10 @@ $args->document_srls = implode(',', $document_srl_list); $document_output = executeQueryArray('document.getDocuments', $args); - foreach($document_output->data as $document) { - $document_list[$document->document_srl] = $document; + if($document_output->data) { + foreach($document_output->data as $document) { + $document_list[$document->document_srl] = $document; + } } } @@ -119,4 +121,4 @@ } } -?> \ No newline at end of file +?> diff --git a/modules/file/file.controller.php b/modules/file/file.controller.php index 7b85a2946..ca4529b57 100644 --- a/modules/file/file.controller.php +++ b/modules/file/file.controller.php @@ -28,8 +28,7 @@ // upload_target_srl 구함 $upload_target_srl = $_SESSION['upload_info'][$editor_sequence]->upload_target_srl; if(!$upload_target_srl) { - $upload_target_srl = getNextSequence(); - $this->setUploadInfo($editor_sequence, $upload_target_srl); + $_SESSION['upload_info'][$editor_sequence]->upload_target_srl = $upload_target_srl = getNextSequence(); } $file_info = Context::get('Filedata'); diff --git a/modules/file/file.model.php b/modules/file/file.model.php index 7df14b982..0e0d06e36 100644 --- a/modules/file/file.model.php +++ b/modules/file/file.model.php @@ -13,6 +13,43 @@ function init() { } + /** + * @brief 특정 문서에 속한 첨부파일 목록을 return + **/ + function getFileList() { + $editor_sequence = Context::get("editor_sequence"); + $upload_target_srl = $_SESSION['upload_info'][$editor_sequence]->upload_target_srl; + if(!$upload_target_srl) exit(); + + $tmp_files = $this->getFiles($upload_target_srl); + $file_count = count($tmp_files); + + for($i=0;$i<$file_count;$i++) { + $file_info = $tmp_files[$i]; + if(!$file_info->file_srl) continue; + + $obj = null; + $obj->file_srl = $file_info->file_srl; + $obj->source_filename = $file_info->source_filename; + $obj->file_size = $file_info->file_size; + $obj->disp_file_size = FileHandler::filesize($file_info->file_size); + if($file_info->direct_download=='N') $obj->download_url = $this->getDownloadUrl($file_info->file_srl, $file_info->sid); + else $obj->download_url = str_replace('./', '', $file_info->uploaded_filename); + $obj->direct_download = $file_info->direct_download; + $files[] = $obj; + $attached_size += $file_info->file_size; + } + + // 업로드 상태 표시 작성 + $upload_status = $this->getUploadStatus($attached_size); + + // 필요한 정보들 세팅 + $this->add("files",$files); + $this->add("editor_sequence",$editor_sequence); + $this->add("upload_target_srl",$upload_target_srl); + $this->add("upload_status",$upload_status); + } + /** * @brief 특정 문서에 속한 첨부파일의 개수를 return **/ @@ -100,8 +137,8 @@ if($logged_info->is_admin == 'Y') { //$file_config->allowed_filesize = 1024; //$file_config->allowed_attach_size = 1024; - $file_config->allowed_filesize = ini_get('upload_max_filesize'); - $file_config->allowed_attach_size = ini_get('upload_max_filesize'); + $file_config->allowed_filesize = preg_replace("/[a-z]/is","",ini_get('upload_max_filesize')); + $file_config->allowed_attach_size = preg_replace("/[a-z]/is","",ini_get('upload_max_filesize')); $file_config->allowed_filetypes = '*.*'; } else { $module_srl = Context::get('module_srl'); diff --git a/modules/page/tpl/page_content_modify.html b/modules/page/tpl/page_content_modify.html index 9b3c6bb66..0896cb1c0 100644 --- a/modules/page/tpl/page_content_modify.html +++ b/modules/page/tpl/page_content_modify.html @@ -22,7 +22,7 @@ - + diff --git a/modules/poll/poll.admin.model.php b/modules/poll/poll.admin.model.php index b6c7df935..31e475c94 100644 --- a/modules/poll/poll.admin.model.php +++ b/modules/poll/poll.admin.model.php @@ -38,7 +38,7 @@ if(!$oDocument->isExists()) $oComment = $oCommentModel->getComment($upload_target_srl); - if($oComment->isExists()) { + if($oComment && $oComment->isExists()) { $this->add('document_srl', $oComment->get('document_srl')); $this->add('comment_srl', $oComment->get('comment_srl')); } elseif($oDocument->isExists()) { diff --git a/modules/widget/tpl/js/widget.js b/modules/widget/tpl/js/widget.js index 7c8c9b789..6c3174b33 100644 --- a/modules/widget/tpl/js/widget.js +++ b/modules/widget/tpl/js/widget.js @@ -165,8 +165,8 @@ function getWidgetCode(childObj, widget) { * 직접 내용을 입력하는 위젯을 추가 **/ // 팝업 띄움 -function doAddContent() { - var url = request_uri.setQuery('module','widget').setQuery('act','dispWidgetAdminAddContent').setQuery('module_srl',zoneModuleSrl); +function doAddContent(mid) { + var url = request_uri.setQuery('module','widget').setQuery('act','dispWidgetAdminAddContent').setQuery('module_srl',zoneModuleSrl).setQuery('mid',mid); popopen(url, "addContent"); } diff --git a/modules/widget/widget.admin.view.php b/modules/widget/widget.admin.view.php index c7654da97..2f1b9b5a8 100644 --- a/modules/widget/widget.admin.view.php +++ b/modules/widget/widget.admin.view.php @@ -49,7 +49,6 @@ $option->enable_component = true; $option->resizable = false; $option->height = 400; - $option->manual_start = false; $editor = $oEditorModel->getEditor($module_srl, $option); Context::set('editor', $editor);
- +
{$upload_status}