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 c423737a5..a8178beec 100644 Binary files a/modules/editor/tpl/images/SWFUpload.swf and b/modules/editor/tpl/images/SWFUpload.swf differ 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}