diff --git a/classes/file/FileHandler.class.php b/classes/file/FileHandler.class.php index e7ebb42d0..57de64d19 100644 --- a/classes/file/FileHandler.class.php +++ b/classes/file/FileHandler.class.php @@ -479,9 +479,11 @@ class FileHandler * @param int $resize_height Height to resize * @param string $target_type If $target_type is set (gif, jpg, png, bmp), result image will be saved as target type * @param string $thumbnail_type Thumbnail type(crop, ratio) + * @param int $quality Compression ratio (0~100) + * @param int $rotate Rotation degrees (0~360) * @return bool TRUE: success, FALSE: failed */ - public static function createImageFile($source_file, $target_file, $resize_width = 0, $resize_height = 0, $target_type = '', $thumbnail_type = 'crop') + public static function createImageFile($source_file, $target_file, $resize_width = 0, $resize_height = 0, $target_type = '', $thumbnail_type = 'crop', $quality = 100, $rotate = 0) { // check params if (($source_file = self::exists($source_file)) === FALSE) @@ -527,6 +529,12 @@ class FileHandler case '6' : $type = 'bmp'; break; + case '8' : + $type = 'wbmp'; + break; + case '18' : + $type = 'webp'; + break; default : return; } @@ -537,49 +545,6 @@ class FileHandler } $target_type = strtolower($target_type); - // if original image is larger than specified size to resize, calculate the ratio - $width_per = ($resize_width > 0 && $width >= $resize_width) ? $resize_width / $width : 1; - $height_per = ($resize_height > 0 && $height >= $resize_height) ? $resize_height / $height : 1; - - $per = NULL; - if($thumbnail_type == 'ratio') - { - $per = ($width_per > $height_per) ? $height_per : $width_per; - $resize_width = $width * $per; - $resize_height = $height * $per; - } - else - { - $per = ($width_per < $height_per) ? $height_per : $width_per; - } - - // create temporary image with target size - $thumb = NULL; - if(function_exists('imagecreateTRUEcolor')) - { - $thumb = imagecreateTRUEcolor($resize_width, $resize_height); - } - else if(function_exists('imagecreate')) - { - $thumb = imagecreate($resize_width, $resize_height); - } - - if(!$thumb) - { - return FALSE; - } - - if($target_type == 'png' && function_exists('imagecolorallocatealpha') && function_exists('imagesavealpha') && function_exists('imagealphablending')) - { - imagefill($thumb, 0, 0, imagecolorallocatealpha($thumb, 0, 0, 0, 127)); - imagesavealpha($thumb, TRUE); - imagealphablending($thumb, TRUE); - } - else - { - imagefilledrectangle($thumb, 0, 0, $resize_width - 1, $resize_height - 1, imagecolorallocate($thumb, 255, 255, 255)); - } - // create temporary image having original type $source = NULL; switch($type) @@ -603,13 +568,24 @@ class FileHandler $source = @imagecreatefrompng($source_file); } break; - case 'wbmp' : case 'bmp' : + if(function_exists('imagecreatefrombmp')) + { + $source = @imagecreatefrombmp($source_file); + } + break; + case 'wbmp' : if(function_exists('imagecreatefromwbmp')) { $source = @imagecreatefromwbmp($source_file); } break; + case 'webp' : + if(function_exists('imagecreatefromwebp')) + { + $source = @imagecreatefromwebp($source_file); + } + break; } if(!$source) @@ -618,27 +594,86 @@ class FileHandler return FALSE; } - // resize original image and put it into temporary image - $new_width = (int) ($width * $per); - $new_height = (int) ($height * $per); - - $x = 0; - $y = 0; - if($thumbnail_type == 'crop') + // Rotate image + if ($rotate) { - $x = (int) ($resize_width / 2 - $new_width / 2); - $y = (int) ($resize_height / 2 - $new_height / 2); + $source = imagerotate($source, $rotate, 0); + $width = imagesx($source); + $height = imagesy($source); } - if(function_exists('imagecopyresampled')) + // If resize not needed, skip thumbnail generation + if ($width == $resize_width && $height == $resize_height) { - imagecopyresampled($thumb, $source, $x, $y, 0, 0, $new_width, $new_height, $width, $height); + $thumb = &$source; } else { - imagecopyresized($thumb, $source, $x, $y, 0, 0, $new_width, $new_height, $width, $height); - } + // if original image is larger than specified size to resize, calculate the ratio + $width_per = ($resize_width > 0 && $width >= $resize_width) ? $resize_width / $width : 1; + $height_per = ($resize_height > 0 && $height >= $resize_height) ? $resize_height / $height : 1; + $per = NULL; + if($thumbnail_type == 'ratio') + { + $per = ($width_per > $height_per) ? $height_per : $width_per; + $resize_width = $width * $per; + $resize_height = $height * $per; + } + else + { + $per = ($width_per < $height_per) ? $height_per : $width_per; + } + + // create temporary image with target size + $thumb = NULL; + if(function_exists('imagecreateTRUEcolor')) + { + $thumb = imagecreateTRUEcolor($resize_width, $resize_height); + } + else if(function_exists('imagecreate')) + { + $thumb = imagecreate($resize_width, $resize_height); + } + + if(!$thumb) + { + return FALSE; + } + + if($target_type == 'png' && function_exists('imagecolorallocatealpha') && function_exists('imagesavealpha') && function_exists('imagealphablending')) + { + imagefill($thumb, 0, 0, imagecolorallocatealpha($thumb, 0, 0, 0, 127)); + imagesavealpha($thumb, TRUE); + imagealphablending($thumb, TRUE); + } + else + { + imagefilledrectangle($thumb, 0, 0, $resize_width - 1, $resize_height - 1, imagecolorallocate($thumb, 255, 255, 255)); + } + + // resize original image and put it into temporary image + $new_width = (int) ($width * $per); + $new_height = (int) ($height * $per); + + $x = 0; + $y = 0; + if($thumbnail_type == 'crop') + { + $x = (int) ($resize_width / 2 - $new_width / 2); + $y = (int) ($resize_height / 2 - $new_height / 2); + } + + if(function_exists('imagecopyresampled')) + { + imagecopyresampled($thumb, $source, $x, $y, 0, 0, $new_width, $new_height, $width, $height); + } + else + { + imagecopyresized($thumb, $source, $x, $y, 0, 0, $new_width, $new_height, $width, $height); + } + } + // create directory self::makeDir(dirname($target_file)); @@ -656,7 +691,7 @@ class FileHandler case 'jpg' : if(function_exists('imagejpeg')) { - $output = imagejpeg($thumb, $target_file, 100); + $output = imagejpeg($thumb, $target_file, $quality); } break; case 'png' : @@ -665,11 +700,22 @@ class FileHandler $output = imagepng($thumb, $target_file, 9); } break; - case 'wbmp' : case 'bmp' : + if(function_exists('imagebmp')) + { + $output = imagebmp($thumb, $target_file); + } + break; + case 'wbmp' : if(function_exists('imagewbmp')) { - $output = imagewbmp($thumb, $target_file, 100); + $output = imagewbmp($thumb, $target_file); + } + break; + case 'webp' : + if(function_exists('imagewebp')) + { + $output = imagewebp($thumb, $target_file); } break; } diff --git a/common/js/plugins/jquery.fileupload/js/main.js b/common/js/plugins/jquery.fileupload/js/main.js index 696ab7569..83b0d71ee 100644 --- a/common/js/plugins/jquery.fileupload/js/main.js +++ b/common/js/plugins/jquery.fileupload/js/main.js @@ -372,12 +372,12 @@ data.uploadTargetSrl = res.uploadTargetSrl; // @TODO 정리 - $container.find('.allowed_filetypes').text(res.allowed_filetypes); + $container.find('.allowed_filetypes').text(res.allowed_extensions.join(', ')); $container.find('.allowed_filesize').text(res.allowed_filesize); $container.find('.allowed_attach_size').text(res.allowed_attach_size); $container.find('.attached_size').text(res.attached_size); $container.find('.file_count').text(res.files.length); - if(res.allowed_filetypes === '*.*') { + if(res.allowed_extensions.length == 0) { $container.find('.allowed_filetypes_container').hide(); } else { $container.find('.allowed_filetypes_container').show(); diff --git a/modules/admin/admin.admin.controller.php b/modules/admin/admin.admin.controller.php index ba5ddb566..7e220e215 100644 --- a/modules/admin/admin.admin.controller.php +++ b/modules/admin/admin.admin.controller.php @@ -758,6 +758,7 @@ class adminAdminController extends admin $document_config = $oDocumentModel->getDocumentConfig(); $document_config->thumbnail_target = $vars->thumbnail_target ?: 'all'; $document_config->thumbnail_type = $vars->thumbnail_type ?: 'crop'; + $document_config->thumbnail_quality = intval($vars->thumbnail_quality) ?: 75; $oModuleController = getController('module'); $oModuleController->insertModuleConfig('document', $document_config); diff --git a/modules/admin/admin.admin.view.php b/modules/admin/admin.admin.view.php index 67ce7107d..58b560d98 100644 --- a/modules/admin/admin.admin.view.php +++ b/modules/admin/admin.admin.view.php @@ -517,6 +517,7 @@ class adminAdminView extends admin $config = $oDocumentModel->getDocumentConfig(); Context::set('thumbnail_target', $config->thumbnail_target ?: 'all'); Context::set('thumbnail_type', $config->thumbnail_type ?: 'crop'); + Context::set('thumbnail_quality', $config->thumbnail_quality ?: 75); if ($config->thumbnail_type === 'none') { Context::set('thumbnail_target', 'none'); diff --git a/modules/admin/lang/en.php b/modules/admin/lang/en.php index d878732f0..0418b6f0b 100644 --- a/modules/admin/lang/en.php +++ b/modules/admin/lang/en.php @@ -270,6 +270,7 @@ $lang->thumbnail_target = 'Extract Thumbnail From'; $lang->thumbnail_target_all = 'All images'; $lang->thumbnail_target_attachment = 'Attached images only'; $lang->thumbnail_type = 'Thumbnail Type'; +$lang->thumbnail_quality = 'Quality'; $lang->input_header_script = 'Header Script'; $lang->detail_input_header_script = 'Content added here will be printed at the top of every page, except the admin module.'; $lang->input_footer_script = 'Footer Script'; diff --git a/modules/admin/lang/ko.php b/modules/admin/lang/ko.php index 47998ca54..79918b73f 100644 --- a/modules/admin/lang/ko.php +++ b/modules/admin/lang/ko.php @@ -273,6 +273,7 @@ $lang->detail_input_footer_script = '모든 페이지의 최하단에 코드를 $lang->thumbnail_crop = '크기에 맞추어 잘라내기'; $lang->thumbnail_ratio = '비율 유지 (여백이 생길 수 있음)'; $lang->thumbnail_none = '썸네일 생성하지 않음'; +$lang->thumbnail_quality = '화질'; $lang->admin_ip_allow = '관리자 로그인 허용 IP'; $lang->admin_ip_deny = '관리자 로그인 금지 IP'; $lang->local_ip_address = '로컬 IP 주소'; diff --git a/modules/admin/tpl/config_advanced.html b/modules/admin/tpl/config_advanced.html index 066e357e4..088889545 100644 --- a/modules/admin/tpl/config_advanced.html +++ b/modules/admin/tpl/config_advanced.html @@ -136,6 +136,11 @@ {$lang->thumbnail_ratio} +
diff --git a/modules/comment/comment.item.php b/modules/comment/comment.item.php index 927a1a767..080c02d26 100644 --- a/modules/comment/comment.item.php +++ b/modules/comment/comment.item.php @@ -656,6 +656,10 @@ class commentItem extends BaseObject { $thumbnail_type = $config->thumbnail_type ?: 'crop'; } + if(!$config->thumbnail_quality) + { + $config->thumbnail_quality = 75; + } if(!$this->isAccessible()) { @@ -785,7 +789,7 @@ class commentItem extends BaseObject if($source_file) { - $output = FileHandler::createImageFile($source_file, $thumbnail_file, $width, $height, 'jpg', $thumbnail_type); + $output = FileHandler::createImageFile($source_file, $thumbnail_file, $width, $height, 'jpg', $thumbnail_type, $config->thumbnail_quality); } // Remove source file if it was temporary diff --git a/modules/document/document.item.php b/modules/document/document.item.php index 302d84a6f..2b2f9b796 100644 --- a/modules/document/document.item.php +++ b/modules/document/document.item.php @@ -1009,6 +1009,10 @@ class documentItem extends BaseObject { $thumbnail_type = $config->thumbnail_type ?: 'crop'; } + if(!$config->thumbnail_quality) + { + $config->thumbnail_quality = 75; + } if(!$this->isAccessible()) { @@ -1143,7 +1147,7 @@ class documentItem extends BaseObject if($source_file) { - $output_file = FileHandler::createImageFile($source_file, $thumbnail_file, $width, $height, 'jpg', $thumbnail_type); + $output_file = FileHandler::createImageFile($source_file, $thumbnail_file, $width, $height, 'jpg', $thumbnail_type, $config->thumbnail_quality); } // Remove source file if it was temporary diff --git a/modules/editor/lang/en.php b/modules/editor/lang/en.php index 2419c8867..77087dfc6 100644 --- a/modules/editor/lang/en.php +++ b/modules/editor/lang/en.php @@ -65,7 +65,7 @@ $lang->msg_auto_saved = 'Automatically Saved.'; $lang->cmd_disable = 'Inactive'; $lang->cmd_enable = 'Active'; $lang->cmd_select_cover = 'Be a cover image'; -$lang->default_editor_settings = 'Default settings for this module'; +$lang->default_editor_settings = 'Use Default Settings'; $lang->editor_skin = 'Editor Skin'; $lang->upload_file_grant = 'Permission to upload files'; $lang->enable_default_component_grant = 'Permission to use default components'; @@ -75,7 +75,7 @@ $lang->enable_autosave = 'Enable Auto-Save'; $lang->allow_html = 'allow HTML'; $lang->height_resizable = 'Height Resizable'; $lang->editor_height = 'Height of Editor'; -$lang->about_default_editor_settings = 'Follow editor settings of Rhymix Admin page through whole site.'; +$lang->about_default_editor_settings = 'Follow the default settings from the Editor module.'; $lang->about_content_font = 'Please use comma for multiple input.'; $lang->about_content_font_size = 'Please input units such as px or em.'; $lang->about_enable_autosave = 'You may decide whether the auto-save function will be used.'; diff --git a/modules/editor/lang/ko.php b/modules/editor/lang/ko.php index 2e80a7ebb..e6abe63e5 100644 --- a/modules/editor/lang/ko.php +++ b/modules/editor/lang/ko.php @@ -79,7 +79,7 @@ $lang->enable_autosave = '자동저장 사용'; $lang->allow_html = 'HTML 허용'; $lang->height_resizable = '높이 조절 가능'; $lang->editor_height = '에디터 높이'; -$lang->about_default_editor_settings = '사이트 전체 에디터 설정을 통일하여서 모듈별 에디터 설정을 단순하게 합니다.'; +$lang->about_default_editor_settings = '에디터 모듈의 기본 설정을 따릅니다.'; $lang->about_content_font = '콤마(,)로 여러 폰트를 지정할 수 있습니다.'; $lang->about_content_font_size = '12px, 1em등 단위까지 포함해서 입력해주세요.'; $lang->about_enable_autosave = '글 작성 시 자동 저장 기능을 활성화 시킬 수 있습니다.'; diff --git a/modules/file/conf/module.xml b/modules/file/conf/module.xml index e43dbd322..fec31a6d2 100644 --- a/modules/file/conf/module.xml +++ b/modules/file/conf/module.xml @@ -14,11 +14,13 @@ - + + - + + diff --git a/modules/file/file.admin.controller.php b/modules/file/file.admin.controller.php index 46ba168a4..1b11dd4f1 100644 --- a/modules/file/file.admin.controller.php +++ b/modules/file/file.admin.controller.php @@ -55,21 +55,26 @@ class fileAdminController extends file } /** - * Add file information + * Save upload configuration * * @return Object */ - function procFileAdminInsertConfig() + function procFileAdminInsertUploadConfig() { - // Get configurations (using module model object) - $config = new stdClass(); + // Update configuration + $config = getModel('module')->getModuleConfig('file'); $config->allowed_filesize = Context::get('allowed_filesize'); $config->allowed_attach_size = Context::get('allowed_attach_size'); - $config->allowed_filetypes = str_replace(' ', '', Context::get('allowed_filetypes')); - $config->allow_outlink = Context::get('allow_outlink'); - $config->allow_outlink_format = Context::get('allow_outlink_format'); - $config->allow_outlink_site = Context::get('allow_outlink_site'); - $config->inline_download_format = array_map('utf8_trim', Context::get('inline_download_format')); + $config->allowed_filetypes = Context::get('allowed_filetypes'); + $config->max_image_width = intval(Context::get('max_image_width')) ?: ''; + $config->max_image_height = intval(Context::get('max_image_height')) ?: ''; + $config->max_image_size_action = Context::get('max_image_size_action') ?: ''; + $config->max_image_size_quality = max(50, min(100, intval(Context::get('max_image_size_quality')))); + $config->image_autoconv['bmp2jpg'] = Context::get('image_autoconv_bmp2jpg') === 'Y' ? true : false; + $config->image_autoconv['webp2jpg'] = Context::get('image_autoconv_webp2jpg') === 'Y' ? true : false; + $config->image_autoconv_quality = max(50, min(100, intval(Context::get('image_autoconv_quality')))); + $config->image_autorotate = Context::get('image_autorotate') === 'Y' ? true : false; + $config->image_autorotate_quality = max(50, min(100, intval(Context::get('image_autorotate_quality')))); // Check maximum file size if (PHP_INT_SIZE < 8) @@ -80,11 +85,52 @@ class fileAdminController extends file } } - // Create module Controller object + // Simplify allowed_filetypes + $config->allowed_extensions = strtr(strtolower(trim($config->allowed_filetypes)), array('*.' => '', ';' => ',')); + if ($config->allowed_extensions) + { + $config->allowed_extensions = array_map('trim', explode(',', $config->allowed_filetypes)); + $config->allowed_filetypes = implode(';', array_map(function($ext) { + return '*.' . $ext; + }, $config->allowed_extensions)); + } + else + { + $config->allowed_extensions = array(); + $config->allowed_filetypes = '*.*'; + } + + // Save and redirect $oModuleController = getController('module'); $output = $oModuleController->insertModuleConfig('file',$config); - $returnUrl = Context::get('success_return_url') ? Context::get('success_return_url') : getNotEncodedUrl('', 'module', 'admin', 'act', 'dispFileAdminConfig'); + $returnUrl = Context::get('success_return_url') ? Context::get('success_return_url') : getNotEncodedUrl('', 'module', 'admin', 'act', 'dispFileAdminUploadConfig'); + return $this->setRedirectUrl($returnUrl, $output); + } + + /** + * Save download configuration + * + * @return Object + */ + function procFileAdminInsertDownloadConfig() + { + // Update configuration + $config = getModel('module')->getModuleConfig('file'); + $config->allow_outlink = Context::get('allow_outlink'); + $config->allow_outlink_format = Context::get('allow_outlink_format'); + $config->allow_outlink_site = Context::get('allow_outlink_site'); + $config->inline_download_format = array_map('utf8_trim', Context::get('inline_download_format')); + + // Save and redirect + $oModuleController = getController('module'); + $output = $oModuleController->insertModuleConfig('file',$config); + if(!$output->toBool()) + { + return $output; + } + + $returnUrl = Context::get('success_return_url') ? Context::get('success_return_url') : getNotEncodedUrl('', 'module', 'admin', 'act', 'dispFileAdminDownloadConfig'); return $this->setRedirectUrl($returnUrl, $output); } @@ -101,24 +147,19 @@ class fileAdminController extends file if(preg_match('/^([0-9,]+)$/',$module_srl)) $module_srl = explode(',',$module_srl); else $module_srl = array($module_srl); - $download_grant = Context::get('download_grant'); - $file_config = new stdClass; - $file_config->allow_outlink = Context::get('allow_outlink'); - $file_config->allow_outlink_format = Context::get('allow_outlink_format'); - $file_config->allow_outlink_site = Context::get('allow_outlink_site'); $file_config->allowed_filesize = Context::get('allowed_filesize'); $file_config->allowed_attach_size = Context::get('allowed_attach_size'); - $file_config->allowed_filetypes = str_replace(' ', '', Context::get('allowed_filetypes')); - - if(!is_array($download_grant)) - { - $file_config->download_grant = explode('|@|',$download_grant); - } - else - { - $file_config->download_grant = array_values($download_grant); - } + $file_config->allowed_filetypes = Context::get('allowed_filetypes'); + $file_config->max_image_width = intval(Context::get('max_image_width')) ?: ''; + $file_config->max_image_height = intval(Context::get('max_image_height')) ?: ''; + $file_config->max_image_size_action = Context::get('max_image_size_action') ?: ''; + $file_config->max_image_size_quality = max(50, min(100, intval(Context::get('max_image_size_quality')))); + $file_config->image_autoconv['bmp2jpg'] = Context::get('image_autoconv_bmp2jpg') === 'Y' ? true : false; + $file_config->image_autoconv['webp2jpg'] = Context::get('image_autoconv_webp2jpg') === 'Y' ? true : false; + $file_config->image_autoconv_quality = max(50, min(100, intval(Context::get('image_autoconv_quality')))); + $file_config->image_autorotate = Context::get('image_autorotate') === 'Y' ? true : false; + $file_config->image_autorotate_quality = max(50, min(100, intval(Context::get('image_autorotate_quality')))); // Check maximum file size if (PHP_INT_SIZE < 8) @@ -129,6 +170,38 @@ class fileAdminController extends file } } + // Simplify allowed_filetypes + $file_config->allowed_extensions = strtr(strtolower(trim($file_config->allowed_filetypes)), array('*.' => '', ';' => ',')); + if ($file_config->allowed_extensions) + { + $file_config->allowed_extensions = array_map('trim', explode(',', $file_config->allowed_filetypes)); + $file_config->allowed_filetypes = implode(';', array_map(function($ext) { + return '*.' . $ext; + }, $file_config->allowed_extensions)); + } + else + { + $file_config->allowed_extensions = array(); + $file_config->allowed_filetypes = '*.*'; + } + + // Use default config + if(Context::get('use_default_file_config') === 'Y') + { + $file_config = new stdClass; + $file_config->use_default_file_config = true; + } + + // Check download grant + $download_grant = Context::get('download_grant'); + if(!is_array($download_grant)) + { + $file_config->download_grant = explode('|@|',$download_grant); + } + else + { + $file_config->download_grant = array_values($download_grant); + } $oModuleController = getController('module'); for($i=0;$igetFileConfig(); @@ -222,7 +222,23 @@ class fileAdminView extends file // Set a template file $this->setTemplatePath($this->module_path.'tpl'); - $this->setTemplateFile('adminConfig'); + $this->setTemplateFile('upload_config'); + } + + /** + * Download config screen + * + * @return Object + */ + function dispFileAdminDownloadConfig() + { + $oFileModel = getModel('file'); + $config = $oFileModel->getFileConfig(); + Context::set('config',$config); + + // Set a template file + $this->setTemplatePath($this->module_path.'tpl'); + $this->setTemplateFile('download_config'); } } /* End of file file.admin.view.php */ diff --git a/modules/file/file.class.php b/modules/file/file.class.php index 67032e4ce..0d8a1924b 100644 --- a/modules/file/file.class.php +++ b/modules/file/file.class.php @@ -21,6 +21,7 @@ class file extends ModuleObject $config->allowed_filesize = '2'; $config->allowed_attach_size = '2'; $config->allowed_filetypes = '*.*'; + $config->allowed_extensions = array(); $oModuleController->insertModuleConfig('file', $config); // Generate a directory for the file module FileHandler::makeDir('./files/attach/images'); diff --git a/modules/file/file.controller.php b/modules/file/file.controller.php index 392511f92..316377665 100644 --- a/modules/file/file.controller.php +++ b/modules/file/file.controller.php @@ -861,48 +861,63 @@ class fileController extends file $file_info['name'] = base64_decode(strtr($match[1], ':', '/')); } + // Sanitize filename + $file_info['name'] = Rhymix\Framework\Filters\FilenameFilter::clean($file_info['name']); + + // Get extension + $extension = explode('.', $file_info['name']) ?: array(''); + $extension = strtolower(array_pop($extension)); + + // Add extra fields to file info array + $file_info['extension'] = $extension; + $file_info['resized'] = false; + + // Get file module configuration + $oFileModel = getModel('file'); + $config = $oFileModel->getFileConfig($module_srl); + + // Check file type + if(!$manual_insert && !$this->user->isAdmin()) + { + + // Check file type + if(isset($config->allowed_extensions) && count($config->allowed_extensions)) + { + if(!in_array($extension, $config->allowed_extensions)) + { + throw new Rhymix\Framework\Exception('msg_not_allowed_filetype'); + } + } + } + + // Check image type and size if(!$manual_insert) { - // Get the file configurations - $logged_info = Context::get('logged_info'); - if($logged_info->is_admin != 'Y') + if(in_array($extension, array('gif', 'jpg', 'jpeg', 'png', 'webp', 'bmp'))) { - $oFileModel = getModel('file'); - $config = $oFileModel->getFileConfig($module_srl); - - // check file type - if(isset($config->allowed_filetypes) && $config->allowed_filetypes !== '*.*') - { - $filetypes = explode(';', $config->allowed_filetypes); - $ext = array(); - foreach($filetypes as $item) { - $item = explode('.', $item); - $ext[] = strtolower($item[1]); - } - $uploaded_ext = explode('.', $file_info['name']); - $uploaded_ext = strtolower(array_pop($uploaded_ext)); - - if(!in_array($uploaded_ext, $ext)) - { - throw new Rhymix\Framework\Exception('msg_not_allowed_filetype'); - } - } - - $allowed_filesize = $config->allowed_filesize * 1024 * 1024; - $allowed_attach_size = $config->allowed_attach_size * 1024 * 1024; - // An error appears if file size exceeds a limit - if($allowed_filesize < filesize($file_info['tmp_name'])) throw new Rhymix\Framework\Exception('msg_exceeds_limit_size'); - // Get total file size of all attachements (from DB) - $size_args = new stdClass; - $size_args->upload_target_srl = $upload_target_srl; - $output = executeQuery('file.getAttachedFileSize', $size_args); - $attached_size = (int)$output->data->attached_size + filesize($file_info['tmp_name']); - if($attached_size > $allowed_attach_size) throw new Rhymix\Framework\Exception('msg_exceeds_limit_size'); + $file_info = $this->checkUploadedImage($file_info, $config); } } - // Sanitize filename - $file_info['name'] = Rhymix\Framework\Filters\FilenameFilter::clean($file_info['name']); + // Check file size + if(!$manual_insert && !$this->user->isAdmin()) + { + $file_size = filesize($file_info['tmp_name']); + $allowed_filesize = $config->allowed_filesize * 1024 * 1024; + $allowed_attach_size = $config->allowed_attach_size * 1024 * 1024; + if($allowed_filesize < $file_size) + { + throw new Rhymix\Framework\Exception('msg_exceeds_limit_size'); + } + + $size_args = new stdClass; + $size_args->upload_target_srl = $upload_target_srl; + $output = executeQuery('file.getAttachedFileSize', $size_args); + if($allowed_attach_size < intval($output->data->attached_size) + $file_size) + { + throw new Rhymix\Framework\Exception('msg_exceeds_limit_size'); + } + } // Get file_srl $file_srl = getNextSequence(); @@ -940,7 +955,7 @@ class fileController extends file } // Move the file - if($manual_insert) + if($manual_insert && !$file_info['converted']) { @copy($file_info['tmp_name'], $filename); if(!file_exists($filename)) @@ -952,7 +967,7 @@ class fileController extends file } } } - elseif(starts_with(RX_BASEDIR . 'files/attach/chunks/', $file_info['tmp_name'])) + elseif(starts_with(RX_BASEDIR . 'files/attach/chunks/', $file_info['tmp_name']) || $file_info['converted']) { if (!Rhymix\Framework\Storage::move($file_info['tmp_name'], $filename)) { @@ -1009,6 +1024,136 @@ class fileController extends file return $output; } + /** + * Check uploaded image + */ + public function checkUploadedImage($file_info, $config) + { + // Get image information + $image_info = @getimagesize($file_info['tmp_name']); + if (!$image_info) + { + return $file_info; + } + + $image_width = $image_info[0]; + $image_height = $image_info[1]; + $image_type = $image_info[2]; + $convert = false; + + // Check image type + if($config->image_autoconv['bmp2jpg'] && function_exists('imagebmp') && $image_type === 6) + { + $convert = array($image_width, $image_height, 'jpg', $config->image_autoconv_quality ?: 75, 0); + } + if($config->image_autoconv['webp2jpg'] && function_exists('imagewebp') && $image_type === 18) + { + $convert = array($image_width, $image_height, 'jpg', $config->image_autoconv_quality ?: 75, 0); + } + + // Check image rotation + if($config->image_autorotate && function_exists('exif_read_data')) + { + $exif = @exif_read_data($file_info['tmp_name']); + if($exif && isset($exif['Orientation'])) + { + switch ($exif['Orientation']) + { + case 3: $rotate = 180; break; + case 6: $rotate = 270; break; + case 8: $rotate = 90; break; + default: $rotate = 0; + } + if ($rotate) + { + $convert = $convert ?: array($image_width, $image_height, $file_info['extension']); + if ($rotate == 90 || $rotate == 270) + { + $image_height = $convert[0]; + $image_width = $convert[1]; + $convert[0] = $image_width; + $convert[1] = $image_height; + } + $convert[3] = $config->image_autorotate_quality ?: 75; + $convert[4] = $rotate; + } + } + unset($exif); + } + + // Check image size + if($config->max_image_size_action && ($config->max_image_width || $config->max_image_height) && !$this->user->isAdmin()) + { + $exceeded = false; + if ($config->max_image_width > 0 && $image_width > $config->max_image_width) + { + $exceeded = true; + } + elseif ($config->max_image_height > 0 && $image_height > $config->max_image_height) + { + $exceeded = true; + } + + if ($exceeded) + { + // Block upload + if ($config->max_image_size_action === 'block') + { + if ($config->max_image_width && $config->max_image_height) + { + $message = sprintf(lang('msg_exceeds_max_image_size'), $config->max_image_width, $config->max_image_height); + } + elseif ($config->max_image_width) + { + $message = sprintf(lang('msg_exceeds_max_image_width'), $config->max_image_width); + } + else + { + $message = sprintf(lang('msg_exceeds_max_image_height'), $config->max_image_height); + } + + throw new Rhymix\Framework\Exception($message); + } + + // Resize automatically + else + { + $resize_width = $image_width; + $resize_height = $image_height; + if ($config->max_image_width > 0 && $image_width > $config->max_image_width) + { + $resize_width = $config->max_image_width; + $resize_height = $image_height * ($config->max_image_width / $image_width); + } + if ($config->max_image_height > 0 && $resize_height > $config->max_image_height) + { + $resize_width = $resize_width * ($config->max_image_height / $resize_height); + $resize_height = $config->max_image_height; + } + $target_type = in_array($image_type, array(6, 8, 18)) ? 'jpg' : $file_info['extension']; + $rotate = ($convert && $convert[4]) ? $convert[4] : 0; + $convert = array(intval($resize_width), intval($resize_height), $target_type, $config->max_image_size_quality ?: 75, $rotate); + } + } + } + + // Convert image if necessary + if ($convert) + { + $result = FileHandler::createImageFile($file_info['tmp_name'], $file_info['tmp_name'] . '.conv', $convert[0], $convert[1], $convert[2], 'crop', $convert[3], $convert[4]); + if ($result) + { + $file_info['name'] = preg_replace('/\.' . preg_quote($file_info['extension'], '/') . '$/i', '.' . $convert[2], $file_info['name']); + $file_info['tmp_name'] = $file_info['tmp_name'] . '.conv'; + $file_info['size'] = filesize($file_info['tmp_name']); + $file_info['extension'] = $convert[2]; + $file_info['converted'] = true; + } + } + + return $file_info; + } + /** * Delete the attachment * diff --git a/modules/file/file.model.php b/modules/file/file.model.php index f3b48d35f..f396c0a71 100644 --- a/modules/file/file.model.php +++ b/modules/file/file.model.php @@ -112,6 +112,7 @@ class fileModel extends file $allowed_attach_size = FileHandler::filesize($file_config->allowed_attach_size*1024*1024); $allowed_filesize = FileHandler::filesize($file_config->allowed_filesize*1024*1024); $allowed_filetypes = $file_config->allowed_filetypes; + $allowed_extensions = $file_config->allowed_extensions; $this->add("files",$files); $this->add("editor_sequence",$editor_sequence); $this->add("upload_target_srl",$upload_target_srl); @@ -121,6 +122,7 @@ class fileModel extends file $this->add('allowed_attach_size', $allowed_attach_size); $this->add('allowed_filesize', $allowed_filesize); $this->add('allowed_filetypes', $allowed_filetypes); + $this->add('allowed_extensions', $allowed_extensions); } /** @@ -185,23 +187,44 @@ class fileModel extends file if($file_config) { + $config->use_default_file_config = $file_config->use_default_file_config; $config->allowed_filesize = $file_config->allowed_filesize; $config->allowed_attach_size = $file_config->allowed_attach_size; $config->allowed_filetypes = $file_config->allowed_filetypes; + $config->allowed_extensions = $file_config->allowed_extensions; $config->inline_download_format = $file_config->inline_download_format; + $config->max_image_width = $file_config->max_image_width; + $config->max_image_height = $file_config->max_image_height; + $config->max_image_size_action = $file_config->max_image_size_action; + $config->max_image_size_quality = $file_config->max_image_size_quality; + $config->image_autoconv = $file_config->image_autoconv; + $config->image_autoconv_quality = $file_config->image_autoconv_quality; + $config->image_autorotate = $file_config->image_autorotate; + $config->image_autorotate_quality = $file_config->image_autorotate_quality; $config->download_grant = $file_config->download_grant; $config->allow_outlink = $file_config->allow_outlink; $config->allow_outlink_site = $file_config->allow_outlink_site; $config->allow_outlink_format = $file_config->allow_outlink_format; } + // Property for all files comes first than each property if(!$config->allowed_filesize) $config->allowed_filesize = $file_module_config->allowed_filesize; if(!$config->allowed_attach_size) $config->allowed_attach_size = $file_module_config->allowed_attach_size; if(!$config->allowed_filetypes) $config->allowed_filetypes = $file_module_config->allowed_filetypes; + if(!$config->allowed_extensions) $config->allowed_extensions = $file_module_config->allowed_extensions; if(!$config->allow_outlink) $config->allow_outlink = $file_module_config->allow_outlink; if(!$config->allow_outlink_site) $config->allow_outlink_site = $file_module_config->allow_outlink_site; if(!$config->allow_outlink_format) $config->allow_outlink_format = $file_module_config->allow_outlink_format; if(!$config->download_grant) $config->download_grant = $file_module_config->download_grant; + if(!$config->max_image_width) $config->max_image_width = $file_module_config->max_image_width; + if(!$config->max_image_height) $config->max_image_height = $file_module_config->max_image_height; + if(!$config->max_image_size_action) $config->max_image_size_action = $file_module_config->max_image_size_action; + if(!$config->max_image_size_quality) $config->max_image_size_quality = $file_module_config->max_image_size_quality; + if(!$config->image_autoconv) $config->image_autoconv = $file_module_config->image_autoconv; + if(!$config->image_autoconv_quality) $config->image_autoconv_quality = $file_module_config->image_autoconv_quality; + if(!$config->image_autorotate) $config->image_autorotate = $file_module_config->image_autorotate; + if(!$config->image_autorotate_quality) $config->image_autorotate_quality = $file_module_config->image_autorotate_quality; + // Default setting if not exists if(!$config->allowed_filesize) $config->allowed_filesize = '2'; if(!$config->allowed_attach_size) $config->allowed_attach_size = '3'; @@ -209,6 +232,26 @@ class fileModel extends file if(!$config->allow_outlink) $config->allow_outlink = 'Y'; if(!$config->download_grant) $config->download_grant = array(); if(!$config->inline_download_format) $config->inline_download_format = array(); + if(!$config->max_image_size_quality) $config->max_image_size_quality = 75; + if(!$config->image_autoconv) $config->image_autoconv = array(); + if(!$config->image_autoconv_quality) $config->image_autoconv_quality = 75; + if(!$config->image_autorotate_quality) $config->image_autorotate_quality = 75; + + // Format allowed_filetypes + if($config->allowed_filetypes && !isset($config->allowed_extensions)) + { + $config->allowed_filetypes = trim($config->allowed_filetypes); + if($config->allowed_filetypes === '*.*') + { + $config->allowed_extensions = ''; + } + else + { + $config->allowed_extensions = array_map(function($ext) { + return strtolower(substr(strrchr(trim($ext), '.'), 1)); + }, explode(';', $config->allowed_filetypes)); + } + } return $config; } diff --git a/modules/file/lang/en.php b/modules/file/lang/en.php index 870a012fb..62ae777ab 100644 --- a/modules/file/lang/en.php +++ b/modules/file/lang/en.php @@ -3,6 +3,7 @@ $lang->file = 'File'; $lang->file_management = 'File Management'; $lang->file_upload = 'File Upload'; $lang->file_upload_config = 'File Upload Settings'; +$lang->file_download_config = 'File Download Settings'; $lang->file_name = 'File Name'; $lang->file_size = 'File Size'; $lang->download_count = 'Number of Downloads'; @@ -16,15 +17,26 @@ $lang->allow_outlink_format = 'Allowed Formats'; $lang->allowed_filesize = 'Maximum File Size'; $lang->allowed_attach_size = 'Maximum Attachments'; $lang->allowed_filetypes = 'Allowed extentsions'; +$lang->max_image_size = 'Maximum Image Size'; +$lang->max_image_size_action_nothing = 'If exceeded, do nothing'; +$lang->max_image_size_action_block = 'If exceeded, block upload'; +$lang->max_image_size_action_resize = 'If exceeded, resize automatically'; +$lang->image_resize_quality = 'Quality'; +$lang->image_autoconv = 'Auto-Convert Image'; +$lang->image_autoconv_bmp2jpg = 'BMP → JPG'; +$lang->image_autoconv_webp2jpg = 'WebP → JPG'; +$lang->image_autorotate = 'Auto-Rotate Image'; $lang->inline_download_format = 'Open in current window'; $lang->inline_download_image = 'Image'; $lang->inline_download_audio = 'Audio'; $lang->inline_download_video = 'Video'; $lang->inline_download_text = 'Text (except HTML)'; $lang->inline_download_pdf = 'PDF'; +$lang->use_default_file_config = 'Use Default Settings'; +$lang->about_use_default_file_config = 'Follow the default settings from the File module.'; $lang->about_inline_download_format = 'Selected types of files will be opened in the current window instead of a download dialog when a user clicks the download link.'; $lang->enable_download_group = 'Downloadable Groups'; -$lang->about_allow_outlink = 'You can block other websites from accessing your download URLs directly.
This does not apply to images and other files that can be embedded directly in a document.'; +$lang->about_allow_outlink = 'Allow other websites to link directly to your download URLs.
Rhymix does not control links to image files that can be embedded directly in a document.
in order to block external links to such images, you may need to modify your web server configuration.'; $lang->about_allow_outlink_format = 'These file formats will always be allowed.
Please use a comma (,) to separate items: e.g. doc, zip, pdf'; $lang->about_allow_outlink_site = 'These referers will always be allowed.
Please enter one full address per line: e.g. https://www.rhymix.org/'; $lang->about_allowed_filesize = 'You can limit the size of each attached file.
Administrators are limited to this setting or the limit set in the file module, whichever is greater.'; @@ -32,7 +44,10 @@ $lang->about_allowed_attach_size = 'You can limit the total size of all attached $lang->about_allowed_filesize_global = 'This is the global limit on the size of each attachment.'; $lang->about_allowed_attach_size_global = 'This is the global limit on the combined size of all attachments in one document.'; $lang->about_allowed_size_limits = 'The file size will be limited to the value set in php.ini (%sB) in IE9 and below and older Android browsers.'; -$lang->about_allowed_filetypes = 'To allow an extension, use "*.[extention]". To allow multiple extensions, use ";" between each extension. ex) *.* or *.jpg;*.gif; '; +$lang->about_allowed_filetypes = 'Rhymix no longer uses the old *.* syntax. Simply list the extensions you wish to allow.
Please use a comma (,) to separate items: e.g. doc, zip, pdf'; +$lang->about_max_image_size = 'You can limit the maximum width and/or height of uploaded images.
This limit does not apply to files uploaded by the administrator.'; +$lang->about_image_autoconv = 'Automatically convert types of images that often cause trouble or waste disk space into other types.
This also works for WebP images that incorrectly have the JPG extension.
If enabled, this feature also applies to images uploaded by the administrator.'; +$lang->about_image_autorotate = 'Automatically correct images that are rotated by mobile devices.
If enabled, this feature also applies to images uploaded by the administrator.'; $lang->cmd_delete_checked_file = 'Delete Selected Item(s)'; $lang->cmd_move_to_document = 'Move to Document'; $lang->cmd_download = 'Download'; @@ -40,6 +55,9 @@ $lang->msg_not_permitted_download = 'You do not have a permission to download.'; $lang->msg_file_cart_is_null = 'Please select a file(s) to delete.'; $lang->msg_checked_file_is_deleted = '%d attachment(s) was(were) deleted.'; $lang->msg_exceeds_limit_size = 'This file exceeds the attachment limit.'; +$lang->msg_exceeds_max_image_size = 'This image is too large. Images must be no larger than %dx%dpx.'; +$lang->msg_exceeds_max_image_width = 'This image is too large. The maximum permitted width is %dpx.'; +$lang->msg_exceeds_max_image_height = 'This image is too large. The maximum permitted height is %dpx.'; $lang->msg_file_not_found = 'Could not find requested file.'; $lang->msg_file_key_expired = 'This download link is expired. Please initiate the download again.'; $lang->file_search_target_list['filename'] = 'File Name'; diff --git a/modules/file/lang/es.php b/modules/file/lang/es.php index 1b3286f9b..ff6e96685 100644 --- a/modules/file/lang/es.php +++ b/modules/file/lang/es.php @@ -17,7 +17,7 @@ $lang->about_allow_outlink = 'Enlaces externos a Rusia Ripper puede bloquear el $lang->about_allow_outlink_site = 'Archivos, independientemente de la configuración para permitir a los enlaces externos es la dirección del sitio. Entrada múltiples gubunhaeju un cambio en la línea, por favor. Ej.) https://www.rhymix.org/'; $lang->about_allowed_filesize = 'Puede definir el límite del tamaño del archivo adjunto.(exceptuando el administrador)'; $lang->about_allowed_attach_size = 'Puede definir el límite del tamaño total de los archivos adjuntos por documento.(exceptuando el administrador)'; -$lang->about_allowed_filetypes = 'Para permitir una extensión use "*.extensión". Para permitir más de una extensión use ";". ej) *.* o *.jpg;*.gif;etc.'; +$lang->about_allowed_filetypes = 'Rhymix ya no usa la antigua sintaxis *. *. Simplemente enumere las extensiones que desea permitir.
Utilice una coma (,) para separar los elementos: doc, zip, pdf'; $lang->cmd_delete_checked_file = 'Eliminar el archivo seleccionado'; $lang->cmd_move_to_document = 'Mover hacia el doncumento'; $lang->cmd_download = 'Descargar'; diff --git a/modules/file/lang/fr.php b/modules/file/lang/fr.php index c0629cd88..933214f56 100644 --- a/modules/file/lang/fr.php +++ b/modules/file/lang/fr.php @@ -13,7 +13,7 @@ $lang->allowed_filetypes = 'Extensions consentis seulement peuvent etre attaches $lang->enable_download_group = 'Groupe permis de telecharger'; $lang->about_allowed_filesize = 'Vous pouvez designer la limite de mesure pour chaque fichier.(Exclure administrateurs)'; $lang->about_allowed_attach_size = 'Vous pouvez designer la limite de mesure pour chaque document.(Exclure administrateurs)'; -$lang->about_allowed_filetypes = 'Pour consentir une extension, utilisez "*.[extention]". Pour consentir plusieurs extensions, utilisez ";" entre chaque extension. ex) *.* ou *.jpg;*.gif;'; +$lang->about_allowed_filetypes = 'Rhymix n\'utilise plus l\'ancienne syntaxe *. *. Indiquez simplement les extensions que vous souhaitez autoriser.
Utilisez une virgule (,) pour séparer les éléments: par exemple. doc, zip, pdf'; $lang->cmd_delete_checked_file = 'Supprimer item(s) slectionne(s)'; $lang->cmd_move_to_document = 'Bouger au Document'; $lang->cmd_download = 'Telecharger'; diff --git a/modules/file/lang/ja.php b/modules/file/lang/ja.php index 87598b65f..0ba2105f1 100644 --- a/modules/file/lang/ja.php +++ b/modules/file/lang/ja.php @@ -22,7 +22,7 @@ $lang->about_allow_outlink_format = '外部からのファイルリンク設定 $lang->about_allow_outlink_site = '外部からのファイルリンク設定に関係なく、常に外部からのリンクを許可するURLです。
複数登録時には、改行で記入してください。 ex) https://www.rhymix.org/'; $lang->about_allowed_filesize = '一つのファイルに対して、アップロード可能なファイルの最大サイズを指定します(管理者は除く)。'; $lang->about_allowed_attach_size = '一つの書き込みに対して、管理者以外のユーザーが添付可能な最大サイズを指定します。'; -$lang->about_allowed_filetypes = '"*.拡張子"で指定し、 ";"で区切って任意の拡張子を追加して指定できます。ex) *.* or *.jpg;*.gif; '; +$lang->about_allowed_filetypes = 'アップロードを許容する拡張者リストです。 前のバージョンの*.* 文法は使用しません。
いろいろな入力時にdoc,zip,pdfのようにコンマ(,)に区分してください。'; $lang->cmd_delete_checked_file = '選択リスト削除'; $lang->cmd_move_to_document = '書き込みに移動する'; $lang->cmd_download = 'ダウンロード'; diff --git a/modules/file/lang/ko.php b/modules/file/lang/ko.php index bc271cbe2..d6dba863e 100644 --- a/modules/file/lang/ko.php +++ b/modules/file/lang/ko.php @@ -3,6 +3,7 @@ $lang->file = '파일'; $lang->file_management = '파일 관리'; $lang->file_upload = '파일 업로드'; $lang->file_upload_config = '파일 업로드 설정'; +$lang->file_download_config = '파일 다운로드 설정'; $lang->file_name = '파일 이름'; $lang->file_size = '파일 크기'; $lang->download_count = '다운로드 받은 수'; @@ -11,28 +12,42 @@ $lang->is_valid = '유효'; $lang->is_stand_by = '대기'; $lang->file_list = '첨부 파일 목록'; $lang->allow_outlink = '다운로드 링크 외부 접근 허용'; -$lang->allow_outlink_site = '다운로드 링크 허용 사이트'; -$lang->allow_outlink_format = '다운로드 링크 허용 확장자'; -$lang->allowed_filesize = '파일 크기 제한'; +$lang->allow_outlink_site = '외부 접근 허용 사이트'; +$lang->allow_outlink_format = '외부 접근 허용 확장자'; +$lang->allowed_filesize = '파일 용량 제한'; $lang->allowed_attach_size = '문서 첨부 제한'; $lang->allowed_filetypes = '허용 확장자'; +$lang->max_image_size = '이미지 크기 제한'; +$lang->max_image_size_action_nothing = '초과시 아무 것도 하지 않음'; +$lang->max_image_size_action_block = '초과시 업로드 금지'; +$lang->max_image_size_action_resize = '초과시 자동 크기 조정'; +$lang->image_resize_quality = '화질'; +$lang->image_autoconv = '이미지 자동 변환'; +$lang->image_autoconv_bmp2jpg = 'BMP → JPG'; +$lang->image_autoconv_webp2jpg = 'WebP → JPG'; +$lang->image_autorotate = '이미지 자동 회전'; $lang->inline_download_format = '다운로드시 현재 창 사용'; $lang->inline_download_image = '이미지'; $lang->inline_download_audio = '오디오'; $lang->inline_download_video = '비디오'; $lang->inline_download_text = '텍스트 (HTML 제외)'; $lang->inline_download_pdf = 'PDF'; +$lang->use_default_file_config = '기본 파일 설정 사용'; +$lang->about_use_default_file_config = '파일 모듈의 기본 설정을 따릅니다.'; $lang->about_inline_download_format = '선택한 종류의 파일은 다운로드 링크를 클릭하더라도 다운로드 창을 열지 않고 현재 창에 표시합니다.'; $lang->enable_download_group = '다운로드 가능 그룹'; -$lang->about_allow_outlink = '다른 사이트에서 파일 다운로드 링크에 직접 접근하는 것을 차단합니다.
다운로드 링크를 사용하지 않고 본문에 바로 삽입할 수 있는 이미지 파일 등에는 적용되지 않습니다.'; +$lang->about_allow_outlink = '다른 사이트에서 파일 다운로드 링크에 직접 접근하는 것을 허용합니다.
본문에 바로 삽입할 수 있는 이미지 파일은 라이믹스에서 접근을 통제할 수 없으며, 이를 차단하려면 웹서버 설정이 필요합니다.'; $lang->about_allow_outlink_format = '파일 외부 링크 설정에 상관없이 허용하는 파일 확장자입니다.
여러 개 입력시 쉼표(,)을 이용해서 구분해 주세요. 예) doc, zip, pdf'; $lang->about_allow_outlink_site = '파일 외부 링크 설정에 상관없이 허용하는 사이트 주소입니다.
여러 개 입력시 줄을 바꿔서 구분해 주세요. 예) https://www.rhymix.org/'; $lang->about_allowed_filesize = '각 파일의 용량을 제한할 수 있습니다.
관리자에게는 이 게시판의 제한과 파일 모듈의 제한 중 높은 쪽이 적용됩니다.'; $lang->about_allowed_attach_size = '하나의 문서에 첨부할 수 있는 최대 용량을 제한할 수 있습니다.
관리자에게는 이 게시판의 제한과 파일 모듈의 제한 중 높은 쪽이 적용됩니다.'; -$lang->about_allowed_filesize_global = '관리자를 포함하여 사이트 전체에 적용되는 파일 크기 제한입니다.'; +$lang->about_allowed_filesize_global = '관리자를 포함하여 사이트 전체에 적용되는 파일 용량 제한입니다.'; $lang->about_allowed_attach_size_global = '관리자를 포함하여 사이트 전체에 적용되는 문서당 총 첨부 용량 제한입니다.'; $lang->about_allowed_size_limits = 'IE9 이하, 구버전 안드로이드 등에서는 php.ini에서 지정한 %sB로 제한됩니다.'; -$lang->about_allowed_filetypes = '"*.확장자"로 지정할 수 있고 ";" 으로 여러 개 지정이 가능합니다. 예) *.* or *.jpg;*.gif;'; +$lang->about_allowed_filetypes = '업로드를 허용할 확장자 목록입니다. 구 버전의 *.* 문법은 사용하지 않습니다.
여러 개 입력시 쉼표(,)을 이용해서 구분해 주세요. 예) doc, zip, pdf'; +$lang->about_max_image_size = '이미지 파일의 가로, 세로, 또는 가로세로 크기를 모두 제한할 수 있습니다.
관리자가 업로드한 파일에는 적용되지 않습니다.'; +$lang->about_image_autoconv = '종종 문제를 일으키거나 용량을 낭비하는 이미지 타입을 다른 타입으로 자동 변환합니다.
WebP 이미지에 JPG 확장자가 잘못 부여된 경우에도 변환할 수 있습니다.
관리자가 업로드한 파일에도 적용됩니다.'; +$lang->about_image_autorotate = '모바일 기기 등에서 잘못 회전된 이미지를 바로잡습니다.
관리자가 업로드한 파일에도 적용됩니다.'; $lang->cmd_delete_checked_file = '선택항목 삭제'; $lang->cmd_move_to_document = '문서로 이동'; $lang->cmd_download = '다운로드'; @@ -41,6 +56,9 @@ $lang->msg_file_cart_is_null = '삭제할 파일을 선택해주세요.'; $lang->msg_checked_file_is_deleted = '%d개의 첨부 파일이 삭제되었습니다.'; $lang->msg_exceeds_limit_size = '허용된 용량을 초과하여 첨부가 되지 않았습니다.'; $lang->msg_not_allowed_filetype = '업로드할 수 없는 파일 형식입니다.'; +$lang->msg_exceeds_max_image_size = '이미지가 너무 큽니다. %dx%dpx 이하의 이미지만 허용됩니다.'; +$lang->msg_exceeds_max_image_width = '이미지가 너무 큽니다. 폭 %dpx 이하의 이미지만 허용됩니다.'; +$lang->msg_exceeds_max_image_height = '이미지가 너무 큽니다. 높이 %dpx 이하의 이미지만 허용됩니다.'; $lang->msg_file_not_found = '요청한 파일을 찾을 수 없습니다.'; $lang->msg_file_key_expired = '다운로드 링크의 유효기간이 지났습니다. 다시 다운로드하여 주시기 바랍니다.'; $lang->file_search_target_list['filename'] = '파일 이름'; diff --git a/modules/file/lang/zh-CN.php b/modules/file/lang/zh-CN.php index 0e15fb82e..cc84af044 100644 --- a/modules/file/lang/zh-CN.php +++ b/modules/file/lang/zh-CN.php @@ -17,7 +17,7 @@ $lang->about_allow_outlink = '根据反向链接防止盗链。(*.wmv, *.mp3等 $lang->about_allow_outlink_site = '可以设置允许外链的站点。多个站点以换行来区分,即一行一个。 ex)https://www.rhymix.org/'; $lang->about_allowed_filesize = '最大单个上传文件大小(管理员不受此限制)。'; $lang->about_allowed_attach_size = '每个主题最大上传文件大小(管理员不受此限制)。'; -$lang->about_allowed_filetypes = '可以用"*.扩展名"来指定或用 ";"来 区分多个扩展名 例) *.* or *.jpg;*.gif;'; +$lang->about_allowed_filetypes = '允许上传的扩展者目录。 不使用前版本的*.*语法。
输入多个时,请与doc,zip,pdf一起用逗号区分。'; $lang->cmd_delete_checked_file = '删除所选项目'; $lang->cmd_move_to_document = '查看源主题'; $lang->cmd_download = '下载'; diff --git a/modules/file/lang/zh-TW.php b/modules/file/lang/zh-TW.php index 9235e3cad..1be588670 100644 --- a/modules/file/lang/zh-TW.php +++ b/modules/file/lang/zh-TW.php @@ -19,7 +19,7 @@ $lang->about_allow_outlink_format = '設定允許外部連結的檔案格式。 $lang->about_allow_outlink_site = '可設置允許外部檔案連結的網站名單。當數量太多時,可換行輸入。 例) https://www.rhymix.org/'; $lang->about_allowed_filesize = '最大單一上傳檔案大小(管理員不受此限制)。'; $lang->about_allowed_attach_size = '每個主題最大上傳檔案大小(管理員不受此限制)。'; -$lang->about_allowed_filetypes = '可以用 "*.副檔名" 來指定或用分號 ";" 來區隔多個副檔名。 例) *.* or *.jpg; *.gif;'; +$lang->about_allowed_filetypes = '允許上傳的擴展者目錄。 不使用前版本的*.*語法。
輸入多個時,請與doc,zip,pdf一起用逗號區分。'; $lang->cmd_delete_checked_file = '刪除所選項目'; $lang->cmd_move_to_document = '檢視原始主題'; $lang->cmd_download = '下載'; diff --git a/modules/file/ruleset/fileModuleConfig.xml b/modules/file/ruleset/fileModuleConfig.xml index 963180a3e..067c5c072 100644 --- a/modules/file/ruleset/fileModuleConfig.xml +++ b/modules/file/ruleset/fileModuleConfig.xml @@ -1,11 +1,7 @@ - - - - diff --git a/modules/file/ruleset/insertConfig.xml b/modules/file/ruleset/insertConfig.xml index 963180a3e..067c5c072 100644 --- a/modules/file/ruleset/insertConfig.xml +++ b/modules/file/ruleset/insertConfig.xml @@ -1,11 +1,7 @@ - - - - diff --git a/modules/file/tpl/css/config.css b/modules/file/tpl/css/config.css new file mode 100644 index 000000000..8dda1fea9 --- /dev/null +++ b/modules/file/tpl/css/config.css @@ -0,0 +1,5 @@ +.use_default_file_config { + margin-top: -10px; + border-bottom: 1px solid #ccc; + background: #f5f5f5; +} \ No newline at end of file diff --git a/modules/file/tpl/adminConfig.html b/modules/file/tpl/download_config.html similarity index 68% rename from modules/file/tpl/adminConfig.html rename to modules/file/tpl/download_config.html index 57f8047d3..16493d05e 100644 --- a/modules/file/tpl/adminConfig.html +++ b/modules/file/tpl/download_config.html @@ -1,13 +1,13 @@ -
+

{$XE_VALIDATOR_MESSAGE}

- - + +
@@ -41,27 +41,6 @@

{$lang->about_inline_download_format}

-
- -
- MB -

{$lang->about_allowed_filesize_global}
{sprintf($lang->about_allowed_size_limits, ini_get('upload_max_filesize'))}

-
-
-
- -
- MB -

{$lang->about_allowed_attach_size_global}
{sprintf($lang->about_allowed_size_limits, ini_get('upload_max_filesize'))}

-
-
-
- -
- -

{$lang->about_allowed_filetypes}

-
-
diff --git a/modules/file/tpl/file_module_config.html b/modules/file/tpl/file_module_config.html index b3a4e35a2..da4f3d4df 100644 --- a/modules/file/tpl/file_module_config.html +++ b/modules/file/tpl/file_module_config.html @@ -1,3 +1,6 @@ + + +

{$lang->file}

@@ -7,6 +10,17 @@ +
+ +
+ +
+
+
diff --git a/modules/file/tpl/header.html b/modules/file/tpl/header.html index e2060cb46..d11c3416f 100644 --- a/modules/file/tpl/header.html +++ b/modules/file/tpl/header.html @@ -7,7 +7,10 @@
  • {$lang->file_list}
  • -
  • - {$lang->file_upload_config} +
  • + {$lang->file_upload_config} +
  • +
  • + {$lang->file_download_config}
  • diff --git a/modules/file/tpl/js/config.js b/modules/file/tpl/js/config.js new file mode 100644 index 000000000..6b37187d5 --- /dev/null +++ b/modules/file/tpl/js/config.js @@ -0,0 +1,12 @@ +(function($) { + $(function() { + + $('#use_default_file_config').on('change', function() { + if ($(this).is(':checked')) { + $('.use_custom_file_config').hide(); + } else { + $('.use_custom_file_config').show(); + } + }); + }); +})(jQuery); diff --git a/modules/file/tpl/upload_config.html b/modules/file/tpl/upload_config.html new file mode 100644 index 000000000..b651b1300 --- /dev/null +++ b/modules/file/tpl/upload_config.html @@ -0,0 +1,96 @@ + + +
    +

    {$XE_VALIDATOR_MESSAGE}

    +
    + + + + + +
    + +
    + MB +

    {$lang->about_allowed_filesize_global}
    {sprintf($lang->about_allowed_size_limits, ini_get('upload_max_filesize'))}

    +
    +
    +
    + +
    + MB +

    {$lang->about_allowed_attach_size_global}
    {sprintf($lang->about_allowed_size_limits, ini_get('upload_max_filesize'))}

    +
    +
    +
    + +
    + × + px   + + +

    {$lang->about_max_image_size}

    +
    +
    +
    + +
    + + + +

    {$lang->about_image_autoconv}

    +
    +
    +
    + +
    + + + +

    {$lang->about_image_autorotate}

    +
    +
    +
    + +
    + +

    {$lang->about_allowed_filetypes}

    +
    +
    +
    +
    + +
    +
    +