동영상 섬네일, GIF로 취급 기능 추가

이미지, 동영상 첨부시 구분할 수 있도록 그 섬네일에 play 아이콘 추가
모듈별 파일 설정시 파일 모듈의 업로드 기본, 이미지, 동영상 설정을 각각 달리 적용할 수 있도록 기본 설정 제어 옵션 분리
This commit is contained in:
conory 2019-09-27 00:34:19 +09:00
parent c2025c4bde
commit cdbc2d7a82
14 changed files with 644 additions and 430 deletions

View file

@ -0,0 +1,46 @@
<?php
namespace Rhymix\Framework;
/**
* The image class.
*/
class Image
{
/**
* Check Check if file is an image
*
* @param string $filename
* @return bool
*/
public static function isImage($filename)
{
return strtolower(array_shift(explode('/', @mime_content_type($filename)))) === 'image';
}
/**
* Get image information
*
* @param string $filename
* @return array|false
*/
public static function getImageInfo($filename)
{
if (!self::isImage($filename))
{
return false;
}
if (!$image_info = @getimagesize($filename))
{
return false;
}
return [
'width' => $image_info[0],
'height' => $image_info[1],
'type' => image_type_to_extension($image_info[2], false),
'bits' => $image_info['bits'],
'channels' => $image_info['channels'],
'mime' => $image_info['mime'],
];
}
}

View file

@ -0,0 +1,20 @@
<?php
namespace Rhymix\Framework;
/**
* The video class.
*/
class Video
{
/**
* Check Check if file is a video
*
* @param string $filename
* @return bool
*/
public static function isVideo($filename)
{
return strtolower(array_shift(explode('/', @mime_content_type($filename)))) === 'video';
}
}

View file

@ -112,7 +112,25 @@
width: 100%;
height: 100%;
}
.xefu-file-video {
position: absolute;
top: 50%;
left: 50%;
margin: -15px;
width: 30px;
height: 30px;
background: rgb(0,0,0,.5);
border-radius: 50%;
}
.xefu-file-video-play {
position: absolute;
top: 50%;
left: 50%;
margin: -8px -5px;
border-width: 8px 0 8px 13px;
border-style: solid;
border-color: transparent transparent transparent #fff;
}
.selected {
}

View file

@ -23,7 +23,8 @@
actSetCover : '.xefu-act-set-cover',
tmplXeUploaderFileitem : '<li class="xefu-file xe-clearfix" data-file-srl="{{file_srl}}"><span class="xefu-file-name">{{source_filename}}</span><span class="xefu-file-info"><span>{{disp_file_size}}</span><span><input type="checkbox" data-file-srl="{{file_srl}}"> Select</span></span></li>',
tmplXeUploaderFileitemImage: '<li class="xefu-file xefu-file-image {{#if cover_image}}xefu-is-cover-image{{/if}}" data-file-srl="{{file_srl}}"><strong class="xefu-file-name">{{source_filename}}</strong><span class="xefu-file-info"><span class="xefu-file-size">{{disp_file_size}}</span><span><img src="{{download_url}}" alt=""></span><span><input type="checkbox" data-file-srl="{{file_srl}}"></span><button class="xefu-act-set-cover" data-file-srl="{{file_srl}}" title="Be a cover image"><i class="xi-check-circle"></i></button></span></li>'
tmplXeUploaderFileitemImage: '<li class="xefu-file xefu-file-image {{#if cover_image}}xefu-is-cover-image{{/if}}" data-file-srl="{{file_srl}}"><strong class="xefu-file-name">{{source_filename}}</strong><span class="xefu-file-info"><span class="xefu-file-size">{{disp_file_size}}</span><span><img src="{{download_url}}" alt=""></span><span><input type="checkbox" data-file-srl="{{file_srl}}"></span><button class="xefu-act-set-cover" data-file-srl="{{file_srl}}" title="Be a cover image"><i class="xi-check-circle"></i></button></span></li>',
tmplXeUploaderFileitemVideo: '<li class="xefu-file xefu-file-image {{#if cover_image}}xefu-is-cover-image{{/if}}" data-file-srl="{{file_srl}}"><strong class="xefu-file-name">{{source_filename}}</strong><span class="xefu-file-info"><span class="xefu-file-size">{{disp_file_size}}</span><span><span class="xefu-file-video"><span class="xefu-file-video-play"></span></span><img src="{{download_url}}" alt=""></span><span><input type="checkbox" data-file-srl="{{file_srl}}"></span><button class="xefu-act-set-cover" data-file-srl="{{file_srl}}" title="Be a cover image"><i class="xi-check-circle"></i></button></span></li>'
};
var _elements = [
@ -156,7 +157,7 @@
else if(/\.(mp3)$/i.test(result.source_filename)) {
temp_code += '<audio src="' + result.download_url + '" controls data-file-srl="' + result.file_srl + '" />';
}
else if(/\.(mp4|webm)$/i.test(result.source_filename)) {
else if(/\.(mp4|webm|ogg)$/i.test(result.source_filename)) {
if(result.original_type === 'gif') {
temp_code += '<video src="' + result.download_url + '" autoplay loop muted data-file-srl="' + result.file_srl + '" />';
} else {
@ -328,7 +329,7 @@
else if(/\.(mp3)$/i.test(result.source_filename)) {
temp_code += '<audio src="' + result.download_url + '" controls data-file-srl="' + result.file_srl + '" />';
}
else if(/\.(mp4|webm)$/i.test(result.source_filename)) {
else if(/\.(mp4|webm|ogg)$/i.test(result.source_filename)) {
if(result.original_type === 'gif') {
temp_code += '<video src="' + result.download_url + '" autoplay loop muted data-file-srl="' + result.file_srl + '" />';
} else {
@ -412,8 +413,10 @@
var tmpl_fileitem = data.settings.tmplXeUploaderFileitem;
var tmpl_fileitem_image = data.settings.tmplXeUploaderFileitemImage;
var tmpl_fileitem_video = data.settings.tmplXeUploaderFileitemVideo;
var template_fileimte = Handlebars.compile(tmpl_fileitem);
var template_fileimte_image = Handlebars.compile(tmpl_fileitem_image);
var template_fileimte_video = Handlebars.compile(tmpl_fileitem_video);
var result_image = [];
var result = [];
@ -434,7 +437,11 @@
file.source_filename = file.source_filename.replace("&amp;", "&");
if(file.thumbnail_filename) {
file.download_url = file.thumbnail_filename;
result_image.push(template_fileimte_image(file));
if(/\.(mp4|webm|ogg)$/i.test(file.source_filename)) {
result_image.push(template_fileimte_video(file));
} else {
result_image.push(template_fileimte_image(file));
}
}
else if(/\.(jpe?g|png|gif|webp)$/i.test(file.source_filename)) {
result_image.push(template_fileimte_image(file));

View file

@ -353,3 +353,8 @@ $lang->license_agreement = 'License Agreement';
$lang->license = 'GPL v2';
$lang->cmd_license_agree = 'I understand the license, and I accept it.';
$lang->msg_must_accept_license_agreement = 'You must accept the license agreement in order to continue.';
$lang->image = 'Image';
$lang->audio = 'Audio';
$lang->video = 'Video';
$lang->text = 'Text';
$lang->image_quality = 'Quality';

View file

@ -357,3 +357,8 @@ $lang->license_agreement = '사용권 동의';
$lang->license = 'GPL v2';
$lang->cmd_license_agree = '사용권에 대해 이해했으며, 이에 동의합니다.';
$lang->msg_must_accept_license_agreement = '사용권에 동의해야 설치를 진행할 수 있습니다.';
$lang->image = '이미지';
$lang->audio = '오디오';
$lang->video = '동영상';
$lang->text = '텍스트';
$lang->image_quality = '화질';

View file

@ -47,11 +47,9 @@ class fileAdminController extends file
$oFileController->deleteFile($file_srl);
}
$this->setMessage( sprintf(lang('msg_checked_file_is_deleted'), $file_count) );
$returnUrl = Context::get('success_return_url') ? Context::get('success_return_url') : getNotEncodedUrl('', 'module', 'admin', 'act', 'dispFileAdminList');
$this->setRedirectUrl($returnUrl);
$this->setMessage(sprintf(lang('msg_checked_file_is_deleted'), $file_count));
$this->setRedirectUrl(Context::get('success_return_url') ?: getNotEncodedUrl('', 'module', 'admin', 'act', 'dispFileAdminList'));
}
/**
@ -66,19 +64,20 @@ class fileAdminController extends file
$config->allowed_filesize = Context::get('allowed_filesize');
$config->allowed_attach_size = Context::get('allowed_attach_size');
$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->max_image_size_admin = Context::get('max_image_size_admin') === 'Y' ? 'Y' : 'N';
$config->image_autoconv['bmp2jpg'] = Context::get('image_autoconv_bmp2jpg') === 'Y' ? true : false;
$config->image_autoconv['png2jpg'] = Context::get('image_autoconv_png2jpg') === 'Y' ? true : false;
$config->image_autoconv['webp2jpg'] = Context::get('image_autoconv_webp2jpg') === 'Y' ? true : false;
$config->image_autoconv['gif2mp4'] = Context::get('image_autoconv_gif2mp4') === 'Y' ? true : false;
$config->image_autoconv_quality = max(50, min(100, intval(Context::get('image_autoconv_quality'))));
$config->ffmpeg_command = escape(utf8_trim(Context::get('ffmpeg_command'))) ?: '/usr/bin/ffmpeg';
$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_admin = Context::get('max_image_size_admin') === 'Y' ? 'Y' : 'N';
$config->image_quality_adjustment = max(50, min(100, intval(Context::get('image_quality_adjustment'))));
$config->image_autorotate = Context::get('image_autorotate') === 'Y' ? true : false;
$config->image_autorotate_quality = max(50, min(100, intval(Context::get('image_autorotate_quality'))));
$config->video_thumbnail = Context::get('video_thumbnail') === 'Y' ? true : false;
$config->video_mp4_gif_time = intval(Context::get('video_mp4_gif_time'));
$config->ffmpeg_command = escape(utf8_trim(Context::get('ffmpeg_command'))) ?: '/usr/bin/ffmpeg';
$config->ffprobe_command = escape(utf8_trim(Context::get('ffprobe_command'))) ?: '/usr/bin/ffprobe';
// Check maximum file size
if (PHP_INT_SIZE < 8)
@ -105,10 +104,8 @@ class fileAdminController extends file
}
// 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', 'dispFileAdminUploadConfig');
$output = getController('module')->insertModuleConfig('file', $config);
$returnUrl = Context::get('success_return_url') ?: getNotEncodedUrl('', 'module', 'admin', 'act', 'dispFileAdminUploadConfig');
return $this->setRedirectUrl($returnUrl, $output);
}
@ -127,14 +124,8 @@ class fileAdminController extends file
$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');
$output = getController('module')->insertModuleConfig('file', $config);
$returnUrl = Context::get('success_return_url') ?: getNotEncodedUrl('', 'module', 'admin', 'act', 'dispFileAdminDownloadConfig');
return $this->setRedirectUrl($returnUrl, $output);
}
@ -150,14 +141,8 @@ class fileAdminController extends file
$config->save_changelog = Context::get('save_changelog') === 'Y' ? 'Y' : 'N';
// 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', 'dispFileAdminOtherConfig');
$output = getController('module')->insertModuleConfig('file', $config);
$returnUrl = Context::get('success_return_url') ?: getNotEncodedUrl('', 'module', 'admin', 'act', 'dispFileAdminOtherConfig');
return $this->setRedirectUrl($returnUrl, $output);
}
@ -168,59 +153,63 @@ class fileAdminController extends file
*/
function procFileAdminInsertModuleConfig()
{
// Get variables
$module_srl = Context::get('target_module_srl');
// In order to configure multiple modules at once
if(preg_match('/^([0-9,]+)$/',$module_srl)) $module_srl = explode(',',$module_srl);
else $module_srl = array($module_srl);
$file_config = new stdClass;
$file_config->allowed_filesize = Context::get('allowed_filesize');
$file_config->allowed_attach_size = Context::get('allowed_attach_size');
$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->max_image_size_admin = Context::get('max_image_size_admin') === 'Y' ? 'Y' : 'N';
$file_config->image_autoconv['bmp2jpg'] = Context::get('image_autoconv_bmp2jpg') === 'Y' ? true : false;
$file_config->image_autoconv['png2jpg'] = Context::get('image_autoconv_png2jpg') === 'Y' ? true : false;
$file_config->image_autoconv['webp2jpg'] = Context::get('image_autoconv_webp2jpg') === 'Y' ? true : false;
$file_config->image_autoconv['gif2mp4'] = Context::get('image_autoconv_gif2mp4') === 'Y' ? true : false;
$file_config->image_autoconv_quality = max(50, min(100, intval(Context::get('image_autoconv_quality'))));
$file_config->ffmpeg_command = escape(utf8_trim(Context::get('ffmpeg_command'))) ?: '/usr/bin/ffmpeg';
$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)
// Default
if(!Context::get('use_default_file_config'))
{
if ($file_config->allowed_filesize > 2047 || $file_config->allowed_attach_size > 2047)
$file_config->use_default_file_config = 'N';
$file_config->allowed_filesize = Context::get('allowed_filesize');
$file_config->allowed_attach_size = Context::get('allowed_attach_size');
$file_config->allowed_filetypes = Context::get('allowed_filetypes');
// Check maximum file size
if (PHP_INT_SIZE < 8)
{
throw new Rhymix\Framework\Exception('msg_32bit_max_2047mb');
if ($file_config->allowed_filesize > 2047 || $file_config->allowed_attach_size > 2047)
{
throw new Rhymix\Framework\Exception('msg_32bit_max_2047mb');
}
}
// 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 = '*.*';
}
}
// Simplify allowed_filetypes
$file_config->allowed_extensions = strtr(strtolower(trim($file_config->allowed_filetypes)), array('*.' => '', ';' => ','));
if ($file_config->allowed_extensions)
// Image
if(!Context::get('use_image_default_file_config'))
{
$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 = '*.*';
$file_config->use_image_default_file_config = 'N';
$file_config->image_autoconv['bmp2jpg'] = Context::get('image_autoconv_bmp2jpg') === 'Y' ? true : false;
$file_config->image_autoconv['png2jpg'] = Context::get('image_autoconv_png2jpg') === 'Y' ? true : false;
$file_config->image_autoconv['webp2jpg'] = Context::get('image_autoconv_webp2jpg') === 'Y' ? true : false;
$file_config->image_autoconv['gif2mp4'] = Context::get('image_autoconv_gif2mp4') === 'Y' ? true : false;
$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_admin = Context::get('max_image_size_admin') === 'Y' ? 'Y' : 'N';
$file_config->image_quality_adjustment = max(50, min(100, intval(Context::get('image_quality_adjustment'))));
$file_config->image_autorotate = Context::get('image_autorotate') === 'Y' ? true : false;
}
// Use default config
if(Context::get('use_default_file_config') === 'Y')
// Video
if(!Context::get('use_video_default_file_config'))
{
$file_config = new stdClass;
$file_config->use_default_file_config = true;
$file_config->use_video_default_file_config = 'N';
$file_config->video_thumbnail = Context::get('video_thumbnail') === 'Y' ? true : false;
$file_config->video_mp4_gif_time = intval(Context::get('video_mp4_gif_time'));
}
// Check download grant
@ -233,19 +222,21 @@ class fileAdminController extends file
{
$file_config->download_grant = array_values($download_grant);
}
// Update
$oModuleController = getController('module');
for($i=0;$i<count($module_srl);$i++)
foreach(explode(',', Context::get('target_module_srl')) as $module_srl)
{
$srl = trim($module_srl[$i]);
if(!$srl) continue;
$oModuleController->insertModulePartConfig('file',$srl,$file_config);
$output = $oModuleController->insertModulePartConfig('file', trim($module_srl), $file_config);
if(!$output->toBool())
{
return $output;
}
}
$this->setError(-1);
$this->setMessage('success_updated', 'info');
$returnUrl = Context::get('success_return_url') ? Context::get('success_return_url') : getNotEncodedUrl('', 'module', 'admin', 'act', 'dispBoardAdminContent');
$this->setRedirectUrl($returnUrl);
$this->setRedirectUrl(Context::get('success_return_url') ?: getNotEncodedUrl('', 'module', 'admin', 'act', 'dispBoardAdminContent'));
}
/**

View file

@ -877,7 +877,7 @@ class fileController extends file
$file_info['name'] = Rhymix\Framework\Filters\FilenameFilter::clean($file_info['name']);
// Add extra fields to file info array
$file_info['extension'] = $original_extension = $this->getExtension($file_info['name']);
$file_info['extension'] = $file_info['original_type'] = $this->getExtension($file_info['name']);
$file_info['converted'] = false;
$file_info['thumbnail'] = null;
@ -897,12 +897,19 @@ class fileController extends file
}
}
// Check image type and size
// Adjust
if(!$manual_insert)
{
if(in_array($file_info['extension'], array('gif', 'jpg', 'jpeg', 'png', 'webp', 'bmp')))
// image
if(in_array($file_info['extension'], ['gif', 'jpg', 'jpeg', 'png', 'webp', 'bmp']))
{
$file_info = $this->checkUploadedImage($file_info, $config);
$file_info = $this->adjustUploadedImage($file_info, $config);
}
// video
if(in_array($file_info['extension'], ['mp4', 'webm', 'ogg']))
{
$file_info = $this->adjustUploadedVideo($file_info, $config);
}
}
@ -938,9 +945,9 @@ class fileController extends file
// Set original type if filename extension is changed
$args->original_type = null;
if($file_info['extension'] !== $original_extension)
if($file_info['extension'] !== $file_info['original_type'])
{
$args->original_type = $original_extension;
$args->original_type = $file_info['original_type'];
}
// Set storage path by checking if the attachement is an image or other kinds of file
@ -1085,42 +1092,44 @@ class fileController extends file
}
/**
* Check uploaded image
* Adjust uploaded image
*/
public function checkUploadedImage($file_info, $config)
public function adjustUploadedImage($file_info, $config)
{
// Get image information
$image_info = @getimagesize($file_info['tmp_name']);
if (!$image_info)
if (!$image_info = Rhymix\Framework\Image::getImageInfo($file_info['tmp_name']))
{
return $file_info;
}
$image_width = $image_info[0];
$image_height = $image_info[1];
$image_type = $image_info[2];
$convert = false;
$adjusted = [
'width' => $image_info['width'],
'height' => $image_info['height'],
'type' => $image_info['type'],
'quality' => $config->image_quality_adjustment,
'rotate' => 0,
];
// Check image type
if($config->image_autoconv['bmp2jpg'] && function_exists('imagebmp') && $image_type === 6)
// Adjust image type
if ($config->image_autoconv['gif2mp4'] && $image_info['type'] === 'gif' && function_exists('exec'))
{
$convert = array($image_width, $image_height, 'jpg', $config->image_autoconv_quality ?: 75, 0);
$adjusted['type'] = 'mp4';
}
if($config->image_autoconv['png2jpg'] && function_exists('imagepng') && $image_type === 3)
elseif ($config->image_autoconv['png2jpg'] && $image_info['type'] === 'png' && function_exists('imagepng'))
{
$convert = array($image_width, $image_height, 'jpg', $config->image_autoconv_quality ?: 75, 0);
$adjusted['type'] = 'jpg';
}
if($config->image_autoconv['webp2jpg'] && function_exists('imagewebp') && $image_type === 18)
elseif ($config->image_autoconv['webp2jpg'] && $image_info['type'] === 'webp' && function_exists('imagewebp'))
{
$convert = array($image_width, $image_height, 'jpg', $config->image_autoconv_quality ?: 75, 0);
$adjusted['type'] = 'jpg';
}
if($config->image_autoconv['gif2mp4'] && function_exists('exec') && $image_type === 1)
elseif ($config->image_autoconv['bmp2jpg'] && $image_info['type'] === 'bmp' && function_exists('imagebmp'))
{
$convert = array($image_width, $image_height, 'mp4', $config->image_autoconv_quality ?: 75, 0);
$adjusted['type'] = 'jpg';
}
// Check image rotation
if($config->image_autorotate && $image_type !== 1 && function_exists('exif_read_data'))
// Adjust image rotation
if ($config->image_autorotate && in_array($image_info['type'], ['jpg', 'jpeg']) && function_exists('exif_read_data'))
{
$exif = @exif_read_data($file_info['tmp_name']);
if($exif && isset($exif['Orientation']))
@ -1134,32 +1143,33 @@ class fileController extends file
}
if ($rotate)
{
$convert = $convert ?: array($image_width, $image_height, $file_info['extension']);
if ($rotate == 90 || $rotate == 270)
if ($rotate === 90 || $rotate === 270)
{
$image_height = $convert[0];
$image_width = $convert[1];
$convert[0] = $image_width;
$convert[1] = $image_height;
$adjusted['width'] = $image_info['height'];
$adjusted['height'] = $image_info['width'];
}
$convert[3] = $config->image_autorotate_quality ?: 75;
$convert[4] = $rotate;
$adjusted['rotate'] = $rotate;
}
}
unset($exif);
}
// Check image size
if($config->max_image_size_action && ($config->max_image_width || $config->max_image_height) && (!$this->user->isAdmin() || $config->max_image_size_admin === 'Y'))
// Adjust image size
if ($config->max_image_size_action && ($config->max_image_width || $config->max_image_height) && (!$this->user->isAdmin() || $config->max_image_size_admin === 'Y'))
{
$exceeded = false;
if ($config->max_image_width > 0 && $image_width > $config->max_image_width)
$exceeded = 0;
$resize_width = $adjusted['width'] * ($config->max_image_height / $adjusted['height']);
$resize_height = $adjusted['height'] * ($config->max_image_width / $adjusted['width']);
if ($config->max_image_width > 0 && $adjusted['width'] > $config->max_image_width)
{
$exceeded = true;
$exceeded++;
$resize_width = $config->max_image_width;
}
elseif ($config->max_image_height > 0 && $image_height > $config->max_image_height)
if ($config->max_image_height > 0 && $adjusted['height'] > $config->max_image_height)
{
$exceeded = true;
$exceeded++;
$resize_height = $config->max_image_height;
}
if ($exceeded)
@ -1183,67 +1193,102 @@ class fileController extends file
throw new Rhymix\Framework\Exception($message);
}
// Resize automatically
else
$adjusted['width'] = (int)$resize_width;
$adjusted['height'] = (int)$resize_height;
if ($image_info['type'] !== 'gif')
{
$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);
$adjusted['type'] = 'jpg';
}
}
}
// Convert image if necessary
if ($convert)
// Convert image if adjusted
if ($image_info['width'] !== $adjusted['width'] || $image_info['height'] !== $adjusted['height'] || $image_info['type'] !== $adjusted['type'] || $adjusted['rotate'])
{
if ($convert[2] === 'mp4')
$output_name = $file_info['tmp_name'] . '.converted.' . $adjusted['type'];
// Create output
if ($adjusted['type'] === 'mp4')
{
$adjusted['width'] -= $adjusted['width'] % 2;
$adjusted['height'] -= $adjusted['height'] % 2;
// Convert using ffmpeg
$command = $config->ffmpeg_command ?: '/usr/bin/ffmpeg';
$command .= ' -i ' . escapeshellarg($file_info['tmp_name']);
$command .= ' -movflags faststart -pix_fmt yuv420p -c:v libx264 -crf 23 -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2"';
$command .= ' ' . escapeshellarg($file_info['tmp_name'] . '.mp4');
$status = @exec($command, $output, $return_var);
$result = $return_var == 0 ? true : false;
$newext = '.mp4';
$command .= ' -movflags +faststart -pix_fmt yuv420p -c:v libx264 -crf 23';
$command .= sprintf(' -vf "scale=%d:%d"', $adjusted['width'], $adjusted['height']);
$command .= ' ' . escapeshellarg($output_name);
@exec($command, $output, $return_var);
$result = $return_var === 0 ? true : false;
// Create thumbnail
if ($result)
{
$file_info['thumbnail'] = $file_info['tmp_name'] . 'thumbnail';
FileHandler::createImageFile($file_info['tmp_name'], $file_info['thumbnail'], $image_width, $image_height, 'jpg');
$file_info['thumbnail'] = $file_info['tmp_name'] . '.thumbnail.jpg';
FileHandler::createImageFile($file_info['tmp_name'], $file_info['thumbnail'], $adjusted['width'], $adjusted['height'], 'jpg');
}
}
else
{
$result = FileHandler::createImageFile($file_info['tmp_name'], $file_info['tmp_name'] . '.conv', $convert[0], $convert[1], $convert[2], 'crop', $convert[3], $convert[4]);
$newext = '.conv';
$result = FileHandler::createImageFile($file_info['tmp_name'], $output_name, $adjusted['width'], $adjusted['height'], $adjusted['type'], 'crop', $adjusted['quality'], $adjusted['rotate']);
}
// Change to information in the output file
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'] . $newext;
$file_info['name'] = preg_replace('/\.' . preg_quote($file_info['extension'], '/') . '$/i', '.' . $adjusted['type'], $file_info['name']);
$file_info['tmp_name'] = $output_name;
$file_info['size'] = filesize($file_info['tmp_name']);
$file_info['extension'] = $convert[2];
$file_info['extension'] = $adjusted['type'];
$file_info['converted'] = true;
}
}
return $file_info;
}
/**
* Adjust uploaded video
*/
public function adjustUploadedVideo($file_info, $config)
{
if (!Rhymix\Framework\Video::isVideo($file_info['tmp_name']))
{
return $file_info;
}
// Create thumbnail
if ($config->video_thumbnail)
{
$output_name = $file_info['tmp_name'] . '.thumbnail.jpeg';
$command = $config->ffmpeg_command ?: '/usr/bin/ffmpeg';
$command .= sprintf(' -ss 00:00:00.%d -i %s -vframes 1', mt_rand(0, 99), escapeshellarg($file_info['tmp_name']));
$command .= ' ' . escapeshellarg($output_name);
@exec($command, $output, $return_var);
if($return_var === 0)
{
$file_info['thumbnail'] = $output_name;
}
}
// Treat as GIF
if ($config->video_mp4_gif_time && $file_info['extension'] === 'mp4')
{
$command = $config->ffprobe_command ?: '/usr/bin/ffprobe';
$command .= ' -i ' . escapeshellarg($file_info['tmp_name']);
$command .= ' -show_entries format=duration -v quiet -of csv="p=0"';
$duration = (int)floor(@exec($command));
if($duration <= $config->video_mp4_gif_time)
{
$file_info['original_type'] = 'gif';
}
}
return $file_info;
}
/**
* Delete the attachment

View file

@ -179,90 +179,43 @@ class fileModel extends file
*/
function getFileConfig($module_srl = null)
{
// Get configurations (using module model object)
$oModuleModel = getModel('module');
$file_module_config = $oModuleModel->getModuleConfig('file');
if($module_srl) $file_config = $oModuleModel->getModulePartConfig('file',$module_srl);
if(!$file_config) $file_config = $file_module_config;
$config = new stdClass();
if($file_config)
$config = $oModuleModel->getModuleConfig('file') ?: new stdClass;
if($module_srl)
{
$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->max_image_size_admin = $file_config->max_image_size_admin;
$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->ffmpeg_command = $file_config->ffmpeg_command;
$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;
$config->save_changelog = $file_config->save_changelog;
$module_config = $oModuleModel->getModulePartConfig('file', $module_srl);
foreach((array)$module_config as $key => $value)
{
$config->$key = $value;
}
}
// 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->max_image_size_admin) $config->max_image_size_admin = $file_module_config->max_image_size_admin;
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;
if(!$config->ffmpeg_command) $config->ffmpeg_command = $file_module_config->ffmpeg_command;
if(!$config->save_changelog) $config->save_changelog = $file_module_config->save_changelog;
// Default setting if not exists
if(!$config->allowed_filesize) $config->allowed_filesize = '2';
if(!$config->allowed_attach_size) $config->allowed_attach_size = '3';
if(!$config->allowed_filetypes) $config->allowed_filetypes = '*.*';
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;
$config->allowed_filesize = $config->allowed_filesize ?? '2';
$config->allowed_attach_size = $config->allowed_attach_size ?? '3';
$config->allow_outlink = $config->allow_outlink ?? 'Y';
$config->download_grant = $config->download_grant ?? [];
$config->inline_download_format = $config->inline_download_format ?? [];
$config->image_autoconv = $config->image_autoconv ?? [];
$config->image_quality_adjustment = $config->image_quality_adjustment ?? 100;
$config->video_mp4_gif_time = $config->video_mp4_gif_time ?? 0;
$config->ffmpeg_command = $config->ffmpeg_command ?? '/usr/bin/ffmpeg';
$config->ffprobe_command = $config->ffprobe_command ?? '/usr/bin/ffmpeg';
// Format allowed_filetypes
if($config->allowed_filetypes && !isset($config->allowed_extensions))
$config->allowed_filetypes = $config->allowed_filetypes ?? '*.*';
if(!isset($config->allowed_extensions))
{
$config->allowed_extensions = [];
$config->allowed_filetypes = trim($config->allowed_filetypes);
if($config->allowed_filetypes === '*.*')
{
$config->allowed_extensions = array();
}
else
if($config->allowed_filetypes !== '*.*')
{
$config->allowed_extensions = array_map(function($ext) {
return strtolower(substr(strrchr(trim($ext), '.'), 1));
}, explode(';', $config->allowed_filetypes));
}
}
return $config;
}

View file

@ -18,19 +18,6 @@ $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->max_image_size_admin = 'Also apply to administrator';
$lang->image_resize_quality = 'Quality';
$lang->image_autoconv = 'Auto-Convert Image';
$lang->image_autoconv_bmp2jpg = 'BMP → JPG';
$lang->image_autoconv_png2jpg = 'PNG → JPG';
$lang->image_autoconv_webp2jpg = 'WebP → JPG';
$lang->image_autoconv_gif2mp4 = 'GIF → MP4';
$lang->ffmpeg_path = 'Path to ffmpeg';
$lang->image_autorotate = 'Auto-Rotate Image';
$lang->inline_download_format = 'Open in current window';
$lang->inline_download_image = 'Image';
$lang->inline_download_audio = 'Audio';
@ -51,10 +38,6 @@ $lang->about_allowed_filesize_global = 'This is the global limit on the size of
$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 = 'Rhymix no longer uses the old *.* syntax. Simply list the extensions you wish to allow.<br />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.<br />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.<br />This also works for WebP images that incorrectly have the JPG extension.<br />If enabled, this feature also applies to images uploaded by the administrator.';
$lang->about_image_autoconv_mp4 = 'Automatically convert animated GIF images into MP4 videos to save storage and bandwidth.<br />Videos may not play properly in older browsers.';
$lang->about_image_autorotate = 'Automatically correct images that are rotated by mobile devices.<br />If enabled, this feature also applies to images uploaded by the administrator.';
$lang->about_save_changelog = 'Keep a log of new and deleted files in the database.';
$lang->cmd_delete_checked_file = 'Delete Selected Item(s)';
$lang->cmd_move_to_document = 'Move to Document';
@ -88,3 +71,32 @@ $lang->msg_32bit_max_2047mb = 'On 32-bit servers, the file size limit cannot exc
$lang->no_files = 'No Files';
$lang->file_manager = 'Manage selected files';
$lang->selected_file = 'Selected files';
$lang->use_image_default_file_config = 'Use Default Settings Of Image File';
$lang->about_use_image_default_file_config = 'Follow the default settings of image file from the File module.';
$lang->use_video_default_file_config = 'Use Default Settings Of Video File';
$lang->about_use_video_default_file_config = 'Follow the video settings of image file from the File module.';
$lang->image_autoconv = 'Image Type';
$lang->about_image_autoconv = 'convert the type of uploaded images. You can fix images that often cause trouble or waste disk space into other types.<br />This also works for WebP images that incorrectly have the JPG extension.';
$lang->image_autoconv_bmp2jpg = 'BMP → JPG';
$lang->image_autoconv_png2jpg = 'PNG → JPG';
$lang->image_autoconv_webp2jpg = 'WebP → JPG';
$lang->max_image_size = 'Image Size';
$lang->about_max_image_size = 'limit the size of uploaded images.<br />This limit does not apply to files uploaded by the administrator.';
$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->max_image_size_admin = 'Also apply to administrator';
$lang->image_quality_adjustment = 'Image Quality';
$lang->about_image_quality_adjustment = 'adjust the quality of uploaded images.';
$lang->original_image_quality = 'Original Quality';
$lang->image_autorotate = 'Fix Image Rotation';
$lang->about_image_autorotate = 'correct images that are rotated by mobile devices.';
$lang->image_autoconv_gif2mp4 = 'Convert GIF';
$lang->about_image_autoconv_gif2mp4 = 'convert animated GIF images into MP4 videos to save storage and bandwidth.<br />Videos may not play properly in older browsers.';
$lang->video_thumbnail = 'Video Thumbnail';
$lang->about_video_thumbnail = 'extract a thumbnail image from uploaded video.';
$lang->video_mp4_gif_time = 'Treat as GIF';
$lang->about_video_mp4_gif_time = 'treat MP4 videos with duration less than the set time as GIF images, and play with auto and loop.';
$lang->ffmpeg_path = 'FFmpeg path';
$lang->ffprobe_path = 'FFprobe path';
$lang->msg_cannot_use_ffmpeg = 'FFmpeg must be available in PHP';

View file

@ -18,23 +18,10 @@ $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->max_image_size_admin = '관리자에게도 적용';
$lang->image_resize_quality = '화질';
$lang->image_autoconv = '이미지 자동 변환';
$lang->image_autoconv_bmp2jpg = 'BMP → JPG';
$lang->image_autoconv_png2jpg = 'PNG → JPG';
$lang->image_autoconv_webp2jpg = 'WebP → JPG';
$lang->image_autoconv_gif2mp4 = 'GIF → MP4';
$lang->ffmpeg_path = 'ffmpeg 경로';
$lang->image_autorotate = '이미지 자동 회전';
$lang->inline_download_format = '다운로드시 현재 창 사용';
$lang->inline_download_image = '이미지';
$lang->inline_download_audio = '오디오';
$lang->inline_download_video = '비디오';
$lang->inline_download_video = '동영상';
$lang->inline_download_text = '텍스트 (HTML 제외)';
$lang->inline_download_pdf = 'PDF';
$lang->file_save_changelog = '변경 내역 기록';
@ -51,10 +38,6 @@ $lang->about_allowed_filesize_global = '관리자를 포함하여 사이트 전
$lang->about_allowed_attach_size_global = '관리자를 포함하여 사이트 전체에 적용되는 문서당 총 첨부 용량 제한입니다.';
$lang->about_allowed_size_limits = 'IE9 이하, 구버전 안드로이드 등에서는 php.ini에서 지정한 %sB로 제한됩니다.';
$lang->about_allowed_filetypes = '업로드를 허용할 확장자 목록입니다. 구 버전의 *.* 문법은 사용하지 않습니다.<br />여러 개 입력시 쉼표(,)을 이용해서 구분해 주세요. 예) doc, zip, pdf';
$lang->about_max_image_size = '이미지 파일의 가로, 세로, 또는 가로세로 크기를 모두 제한할 수 있습니다.<br />관리자가 업로드한 파일에는 적용되지 않습니다.';
$lang->about_image_autoconv = '종종 문제를 일으키거나 용량을 낭비하는 이미지 타입을 다른 타입으로 자동 변환합니다.<br />WebP 이미지에 JPG 확장자가 잘못 부여된 경우에도 변환할 수 있습니다.<br />관리자가 업로드한 파일에도 적용됩니다.';
$lang->about_image_autoconv_mp4 = '움직이는 GIF 이미지를 MP4 동영상으로 변환하여 용량 및 트래픽을 절약합니다.<br />구형 브라우저에서는 동영상이 재생되지 않을 수도 있습니다.';
$lang->about_image_autorotate = '모바일 기기 등에서 잘못 회전된 이미지를 바로잡습니다.<br />관리자가 업로드한 파일에도 적용됩니다.';
$lang->about_save_changelog = '파일 저장 및 삭제 내역을 DB에 기록합니다.';
$lang->cmd_delete_checked_file = '선택항목 삭제';
$lang->cmd_move_to_document = '문서로 이동';
@ -89,3 +72,32 @@ $lang->msg_32bit_max_2047mb = '32비트 서버에서는 파일 크기 제한이
$lang->no_files = '파일이 없습니다.';
$lang->file_manager = '선택한 파일 관리';
$lang->selected_file = '선택한 파일';
$lang->use_image_default_file_config = '이미지 파일 기본 설정 사용';
$lang->about_use_image_default_file_config = '파일 모듈의 이미지 파일 기본 설정을 따릅니다.';
$lang->use_video_default_file_config = '동영상 파일 기본 설정 사용';
$lang->about_use_video_default_file_config = '파일 모듈의 동영상 파일 기본 설정을 따릅니다.';
$lang->image_autoconv = '이미지 타입';
$lang->about_image_autoconv = '업로드된 이미지의 타입을 변환합니다. 종종 문제를 일으키거나 용량을 낭비하는 이미지를 해결할 수 있습니다.<br />WebP 이미지에 JPG 확장자가 잘못 부여된 경우에도 변환할 수 있습니다.';
$lang->image_autoconv_bmp2jpg = 'BMP → JPG';
$lang->image_autoconv_png2jpg = 'PNG → JPG';
$lang->image_autoconv_webp2jpg = 'WebP → JPG';
$lang->max_image_size = '이미지 크기';
$lang->about_max_image_size = '업로드된 이미지의 크기를 제한하거나 조정합니다. 관리자가 업로드한 파일에는 적용되지 않습니다.';
$lang->max_image_size_action_nothing = '초과시 아무 것도 하지 않음';
$lang->max_image_size_action_block = '초과시 업로드 금지';
$lang->max_image_size_action_resize = '초과시 자동 크기 조정';
$lang->max_image_size_admin = '관리자에게도 적용';
$lang->image_quality_adjustment = '이미지 화질';
$lang->about_image_quality_adjustment = '업로드된 이미지의 화질을 조정합니다.';
$lang->original_image_quality = '원본 화질';
$lang->image_autorotate = '이미지 회전 수정';
$lang->about_image_autorotate = '모바일 기기 등에서 잘못 회전된 이미지를 바로잡습니다.';
$lang->image_autoconv_gif2mp4 = 'GIF 변환';
$lang->about_image_autoconv_gif2mp4 = '움직이는 GIF 이미지를 MP4 동영상으로 변환하여 용량 및 트래픽을 절약합니다.<br />구형 브라우저에서는 동영상이 재생되지 않을 수도 있습니다.';
$lang->video_thumbnail = '동영상 섬네일';
$lang->about_video_thumbnail = '업로드된 동영상에서 섬네일 이미지를 추출합니다.';
$lang->video_mp4_gif_time = 'GIF로 취급';
$lang->about_video_mp4_gif_time = '설정된 시간 이하의 길이를 가진 짧은 MP4 동영상을 GIF 이미지로 취급하여 자동 및 반복 재생 상태로 삽입합니다.';
$lang->ffmpeg_path = 'FFmpeg 경로';
$lang->ffprobe_path = 'FFprobe 경로';
$lang->msg_cannot_use_ffmpeg = 'PHP에서 FFmpeg를 사용할 수 있어야 합니다.';

View file

@ -8,117 +8,159 @@
<input type="hidden" name="module" value="file" />
<input type="hidden" name="act" value="procFileAdminInsertModuleConfig" />
<input type="hidden" name="success_return_url" value="{getRequestUriByServerEnviroment()}" />
<input type="hidden" name="target_module_srl" value="{$module_info->module_srl?$module_info->module_srl:$module_srls}" />
<input type="hidden" name="target_module_srl" value="{$module_info->module_srl ?: $module_srls}" />
<div class="x_control-group use_default_file_config">
<label for="allowed_filesize" class="x_control-label">{$lang->use_default_file_config}</label>
<label class="x_control-label">{$lang->use_default_file_config}</label>
<div class="x_controls">
<label for="use_default_file_config" class="x_inline">
<input type="checkbox" name="use_default_file_config" id="use_default_file_config" value="Y" checked="checked"|cond="$file_config->use_default_file_config" />
<input type="checkbox" name="use_default_file_config" id="use_default_file_config" value="Y" checked="checked"|cond="$file_config->use_default_file_config !== 'N'" />
{$lang->about_use_default_file_config}
</label>
</div>
</div>
<div class="use_custom_file_config" style="display:none"|cond="$file_config->use_default_file_config">
<div class="x_control-group">
<label for="allowed_filesize" class="x_control-label">{$lang->allowed_filesize}</label>
<div class="x_controls">
<input type="number" min="0" name="allowed_filesize" id="allowed_filesize" value="{$file_config->allowed_filesize}" size="7" style="min-width:80px" /> MB
<p class="x_help-block">{sprintf($lang->about_allowed_filesize, getUrl('', 'module', 'admin', 'act', 'dispFileAdminConfig'))}<br />{sprintf($lang->about_allowed_size_limits, ini_get('upload_max_filesize'))}</p>
<div class="use_custom_file_config" style="display:none"|cond="$file_config->use_default_file_config !== 'N'">
<div class="x_control-group">
<label for="allowed_filesize" class="x_control-label">{$lang->allowed_filesize}</label>
<div class="x_controls">
<input type="number" min="0" name="allowed_filesize" id="allowed_filesize" value="{$file_config->allowed_filesize}" size="7" style="min-width:80px" /> MB
<p class="x_help-block">{sprintf($lang->about_allowed_filesize, getUrl('', 'module', 'admin', 'act', 'dispFileAdminConfig'))}<br />{sprintf($lang->about_allowed_size_limits, ini_get('upload_max_filesize'))}</p>
</div>
</div>
<div class="x_control-group">
<label for="allowed_attach_size" class="x_control-label">{$lang->allowed_attach_size}</label>
<div class="x_controls">
<input type="number" min="0" name="allowed_attach_size" id="allowed_attach_size" value="{$file_config->allowed_attach_size}" size="7" style="min-width:80px" /> MB
<p class="x_help-block">{sprintf($lang->about_allowed_attach_size, getUrl('', 'module', 'admin', 'act', 'dispFileAdminConfig'))}<br />{sprintf($lang->about_allowed_size_limits, ini_get('upload_max_filesize'))}</p>
</div>
</div>
<div class="x_control-group">
<label for="allowed_filetypes" class="x_control-label">{$lang->allowed_filetypes}</label>
<div class="x_controls">
<input type="text" name="allowed_filetypes" id="allowed_filetypes" value="{implode(', ', $file_config->allowed_extensions)}" />
<p class="x_help-block">{$lang->about_allowed_filetypes}</p>
</div>
</div>
</div>
<div class="x_control-group">
<label for="allowed_attach_size" class="x_control-label">{$lang->allowed_attach_size}</label>
<div class="x_control-group use_default_file_config">
<label class="x_control-label">{$lang->use_image_default_file_config}</label>
<div class="x_controls">
<input type="number" min="0" name="allowed_attach_size" id="allowed_attach_size" value="{$file_config->allowed_attach_size}" size="7" style="min-width:80px" /> MB
<p class="x_help-block">{sprintf($lang->about_allowed_attach_size, getUrl('', 'module', 'admin', 'act', 'dispFileAdminConfig'))}<br />{sprintf($lang->about_allowed_size_limits, ini_get('upload_max_filesize'))}</p>
<label for="use_image_default_file_config" class="x_inline">
<input type="checkbox" name="use_image_default_file_config" id="use_image_default_file_config" value="Y" checked="checked"|cond="$file_config->use_image_default_file_config !== 'N'" />
{$lang->about_use_image_default_file_config}
</label>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{$lang->max_image_size}</label>
<div class="x_controls">
<input type="number" min="0" name="max_image_width" id="max_image_width" value="{$file_config->max_image_width}" size="7" style="min-width:80px" /> &times;
<input type="number" min="0" name="max_image_height" id="max_image_height" value="{$file_config->max_image_height}" size="7" style="min-width:80px" /> px &nbsp;
<select name="max_image_size_action" id="max_image_size_action">
<option value="" selected="selected"|cond="$file_config->max_image_size_action == ''">{$lang->max_image_size_action_nothing}</option>
<option value="block" selected="selected"|cond="$file_config->max_image_size_action == 'block'">{$lang->max_image_size_action_block}</option>
<option value="resize" selected="selected"|cond="$file_config->max_image_size_action == 'resize'">{$lang->max_image_size_action_resize}</option>
</select>
<select name="max_image_size_quality" id="max_image_size_quality" style="width:100px;min-width:100px">
{@ $file_config->max_image_size_quality = $file_config->max_image_size_quality ?: 75}
<!--@for($q = 50; $q <= 100; $q += 5)-->
<option value="{$q}" selected="selected"|cond="$file_config->max_image_size_quality == $q">{$lang->image_resize_quality} {$q}%</option>
<!--@endfor-->
</select>
<p class="x_help-block">
{$lang->about_max_image_size}
<label for="max_image_size_admin">
<input type="checkbox" name="max_image_size_admin" id="max_image_size_admin" value="Y" checked="checked"|cond="$file_config->max_image_size_admin === 'Y'" />
{$lang->max_image_size_admin}
<div class="use_custom_image_file_config" style="display:none"|cond="$file_config->use_image_default_file_config !== 'N'">
<div class="x_control-group">
<label class="x_control-label">{$lang->image_autoconv}</label>
<div class="x_controls">
<label for="image_autoconv_bmp2jpg">
<input type="checkbox" name="image_autoconv_bmp2jpg" id="image_autoconv_bmp2jpg" value="Y" checked="checked"|cond="$file_config->image_autoconv['bmp2jpg']" disabled="disabled"|cond="!function_exists('imagebmp')" />
{$lang->image_autoconv_bmp2jpg}
</label>
</p>
<label for="image_autoconv_png2jpg">
<input type="checkbox" name="image_autoconv_png2jpg" id="image_autoconv_png2jpg" value="Y" checked="checked"|cond="$file_config->image_autoconv['png2jpg']" disabled="disabled"|cond="!function_exists('imagepng')" />
{$lang->image_autoconv_png2jpg}
</label>
<label for="image_autoconv_webp2jpg">
<input type="checkbox" name="image_autoconv_webp2jpg" id="image_autoconv_webp2jpg" value="Y" checked="checked"|cond="$file_config->image_autoconv['webp2jpg']" disabled="disabled"|cond="!function_exists('imagewebp')" />
{$lang->image_autoconv_webp2jpg}
</label>
<p class="x_help-block">{$lang->about_image_autoconv}</p>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{$lang->max_image_size}</label>
<div class="x_controls">
<input type="number" min="0" name="max_image_width" id="max_image_width" value="{$file_config->max_image_width}" size="7" style="min-width:80px" /> &times;
<input type="number" min="0" name="max_image_height" id="max_image_height" value="{$file_config->max_image_height}" size="7" style="min-width:80px" /> px &nbsp;
<select name="max_image_size_action" id="max_image_size_action">
<option value="">{$lang->max_image_size_action_nothing}</option>
<option value="block" selected="selected"|cond="$file_config->max_image_size_action === 'block'">{$lang->max_image_size_action_block}</option>
<option value="resize" selected="selected"|cond="$file_config->max_image_size_action === 'resize'">{$lang->max_image_size_action_resize}</option>
</select>
<p class="x_help-block">
{$lang->about_max_image_size}
<label for="max_image_size_admin">
<input type="checkbox" name="max_image_size_admin" id="max_image_size_admin" value="Y" checked="checked"|cond="$file_config->max_image_size_admin === 'Y'" />
{$lang->max_image_size_admin}
</label>
</p>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{$lang->image_quality_adjustment}</label>
<div class="x_controls">
<select name="image_quality_adjustment" style="min-width:80px">
<!--@for($q = 50; $q <= 100; $q += 5)-->
<option value="{$q}" selected="selected"|cond="$file_config->image_quality_adjustment === $q"><!--@if($q === 100)-->{$lang->original_image_quality}<!--@else-->{$q}%<!--@end--></option>
<!--@endfor-->
</select>
<p class="x_help-block">{$lang->about_image_quality_adjustment}</p>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{$lang->image_autorotate}</label>
<div class="x_controls">
<label for="image_autorotate_Y" class="x_inline">
<input type="radio" name="image_autorotate" id="image_autorotate_Y" value="Y" checked="checked"|cond="$file_config->image_autorotate === true" disabled="disabled"|cond="!function_exists('exif_read_data')" />
{$lang->cmd_yes}
</label>
<label for="image_autorotate_N" class="x_inline">
<input type="radio" name="image_autorotate" id="image_autorotate_N" value="N" checked="checked"|cond="$file_config->image_autorotate !== true" disabled="disabled"|cond="!function_exists('exif_read_data')" />
{$lang->cmd_no}
</label>
<p class="x_help-block">{$lang->about_image_autorotate}</p>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{$lang->image_autoconv_gif2mp4}</label>
<div class="x_controls">
<label for="image_autoconv_gif2mp4_Y" class="x_inline">
<input type="radio" name="image_autoconv_gif2mp4" id="image_autoconv_gif2mp4_Y" value="Y" checked="checked"|cond="$file_config->image_autoconv['gif2mp4'] === true" disabled="disabled"|cond="!function_exists('exec')" />
{$lang->cmd_yes}
</label>
<label for="image_autoconv_gif2mp4_N" class="x_inline">
<input type="radio" name="image_autoconv_gif2mp4" id="image_autoconv_gif2mp4_N" value="N" checked="checked"|cond="$file_config->image_autoconv['gif2mp4'] !== true" disabled="disabled"|cond="!function_exists('exec')" />
{$lang->cmd_no}
</label>
<p class="x_help-block">{$lang->about_image_autoconv_gif2mp4}</p>
</div>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{$lang->image_autoconv}</label>
<div class="x_control-group use_default_file_config">
<label class="x_control-label">{$lang->use_video_default_file_config}</label>
<div class="x_controls">
<label for="image_autoconv_bmp2jpg" class="x_inline">
<input type="checkbox" name="image_autoconv_bmp2jpg" id="image_autoconv_bmp2jpg" value="Y" checked="checked"|cond="$file_config->image_autoconv['bmp2jpg']" disabled="disabled"|cond="!function_exists('imagebmp')" />
{$lang->image_autoconv_bmp2jpg}
<label for="use_video_default_file_config" class="x_inline">
<input type="checkbox" name="use_video_default_file_config" id="use_video_default_file_config" value="Y" checked="checked"|cond="$file_config->use_video_default_file_config !== 'N'" />
{$lang->about_use_video_default_file_config}
</label>
<label for="image_autoconv_png2jpg" class="x_inline">
<input type="checkbox" name="image_autoconv_png2jpg" id="image_autoconv_png2jpg" value="Y" checked="checked"|cond="$file_config->image_autoconv['png2jpg']" disabled="disabled"|cond="!function_exists('imagepng')" />
{$lang->image_autoconv_png2jpg}
</label>
<label for="image_autoconv_webp2jpg" class="x_inline">
<input type="checkbox" name="image_autoconv_webp2jpg" id="image_autoconv_webp2jpg" value="Y" checked="checked"|cond="$file_config->image_autoconv['webp2jpg']" disabled="disabled"|cond="!function_exists('imagewebp')" />
{$lang->image_autoconv_webp2jpg}
</label>
<select name="image_autoconv_quality" id="image_autoconv_quality" style="width:100px;min-width:100px">
{@ $file_config->image_autoconv_quality = $file_config->image_autoconv_quality ?: 75}
<!--@for($q = 50; $q <= 100; $q += 5)-->
<option value="{$q}" selected="selected"|cond="$file_config->image_autoconv_quality == $q">{$lang->image_resize_quality} {$q}%</option>
<!--@endfor-->
</select>
<p class="x_help-block" style="margin-bottom:10px">{$lang->about_image_autoconv}</p>
<label for="image_autoconv_gif2mp4" class="x_inline">
<input type="checkbox" name="image_autoconv_gif2mp4" id="image_autoconv_gif2mp4" value="Y" checked="checked"|cond="$file_config->image_autoconv['gif2mp4']" disabled="disabled"|cond="!function_exists('exec')" />
{$lang->image_autoconv_gif2mp4}
</label>
<input type="text" name="ffmpeg_command" id="ffmpeg_command" value="{$file_config->ffmpeg_command ?: '/usr/bin/ffmpeg'}" placeholder="{$lang->ffmpeg_path}" />
<p class="x_help-block">{$lang->about_image_autoconv_mp4}</p>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{$lang->image_autorotate}</label>
<div class="x_controls">
<label for="image_autorotate_Y" class="x_inline">
<input type="radio" name="image_autorotate" id="image_autorotate_Y" value="Y" checked="checked"|cond="$file_config->image_autorotate === true" disabled="disabled"|cond="!function_exists('exif_read_data')" />
{$lang->cmd_yes}
</label>
<label for="image_autorotate_N" class="x_inline">
<input type="radio" name="image_autorotate" id="image_autorotate_N" value="N" checked="checked"|cond="$file_config->image_autorotate !== true" disabled="disabled"|cond="!function_exists('exif_read_data')" />
{$lang->cmd_no}
</label>
<select name="image_autorotate_quality" id="image_autorotate_quality" style="width:100px;min-width:100px">
{@ $file_config->image_autorotate_quality = $file_config->image_autorotate_quality ?: 75}
<!--@for($q = 50; $q <= 100; $q += 5)-->
<option value="{$q}" selected="selected"|cond="$file_config->image_autorotate_quality == $q">{$lang->image_resize_quality} {$q}%</option>
<!--@endfor-->
</select>
<p class="x_help-block">{$lang->about_image_autorotate}</p>
<div class="use_custom_video_file_config" style="display:none"|cond="$file_config->use_video_default_file_config !== 'N'">
<div class="x_control-group">
<label class="x_control-label">{$lang->video_thumbnail}</label>
<div class="x_controls">
<label for="video_thumbnail_Y" class="x_inline">
<input type="radio" name="video_thumbnail" id="video_thumbnail_Y" value="Y" checked="checked"|cond="$file_config->video_thumbnail === true" disabled="disabled"|cond="!function_exists('exec')" />
{$lang->cmd_yes}
</label>
<label for="video_thumbnail_N" class="x_inline">
<input type="radio" name="video_thumbnail" id="video_thumbnail_N" value="N" checked="checked"|cond="$file_config->video_thumbnail !== true" disabled="disabled"|cond="!function_exists('exec')" />
{$lang->cmd_no}
</label>
<p class="x_help-block">{$lang->about_video_thumbnail}</p>
</div>
</div>
</div>
<div class="x_control-group">
<label for="allowed_filetypes" class="x_control-label">{$lang->allowed_filetypes}</label>
<div class="x_controls">
<input type="text" name="allowed_filetypes" id="allowed_filetypes" value="{implode(', ', $file_config->allowed_extensions ?: [])}" />
<p class="x_help-block">{$lang->about_allowed_filetypes}</p>
<div class="x_control-group">
<label class="x_control-label">{$lang->video_mp4_gif_time}</label>
<div class="x_controls">
<input type="number" min="0" name="video_mp4_gif_time" value="{$file_config->video_mp4_gif_time}" style="min-width:80px" disabled="disabled"|cond="!function_exists('exec')" /> {$lang->unit_sec}
<p class="x_help-block">{$lang->about_video_mp4_gif_time}</p>
</div>
</div>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{$lang->enable_download_group}</label>
<div class="x_controls">

View file

@ -1,6 +1,5 @@
(function($) {
$(function() {
$('#use_default_file_config').on('change', function() {
if ($(this).is(':checked')) {
$('.use_custom_file_config').hide();
@ -8,5 +7,19 @@
$('.use_custom_file_config').show();
}
});
$('#use_image_default_file_config').on('change', function() {
if ($(this).is(':checked')) {
$('.use_custom_image_file_config').hide();
} else {
$('.use_custom_image_file_config').show();
}
});
$('#use_video_default_file_config').on('change', function() {
if ($(this).is(':checked')) {
$('.use_custom_video_file_config').hide();
} else {
$('.use_custom_video_file_config').show();
}
});
});
})(jQuery);

View file

@ -8,6 +8,7 @@
<input type="hidden" name="module" value="file" />
<input type="hidden" name="act" value="procFileAdminInsertUploadConfig" />
<input type="hidden" name="xe_validator_id" value="modules/file/tpl/upload_config/1" />
<div class="x_control-group">
<label for="allowed_filesize" class="x_control-label">{$lang->allowed_filesize}</label>
<div class="x_controls">
@ -22,88 +23,132 @@
<p class="x_help-block">{$lang->about_allowed_attach_size_global}<br />{sprintf($lang->about_allowed_size_limits, ini_get('upload_max_filesize'))}</p>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{$lang->max_image_size}</label>
<div class="x_controls">
<input type="number" min="0" name="max_image_width" id="max_image_width" value="{$config->max_image_width}" size="7" style="min-width:80px" /> &times;
<input type="number" min="0" name="max_image_height" id="max_image_height" value="{$config->max_image_height}" size="7" style="min-width:80px" /> px &nbsp;
<select name="max_image_size_action" id="max_image_size_action">
<option value="" selected="selected"|cond="$config->max_image_size_action == ''">{$lang->max_image_size_action_nothing}</option>
<option value="block" selected="selected"|cond="$config->max_image_size_action == 'block'">{$lang->max_image_size_action_block}</option>
<option value="resize" selected="selected"|cond="$config->max_image_size_action == 'resize'">{$lang->max_image_size_action_resize}</option>
</select>
<select name="max_image_size_quality" id="max_image_size_quality" style="width:100px;min-width:100px">
{@ $config->max_image_size_quality = $config->max_image_size_quality ?: 75}
<!--@for($q = 50; $q <= 100; $q += 5)-->
<option value="{$q}" selected="selected"|cond="$config->max_image_size_quality == $q">{$lang->image_resize_quality} {$q}%</option>
<!--@endfor-->
</select>
<p class="x_help-block">
{$lang->about_max_image_size}
<label for="max_image_size_admin">
<input type="checkbox" name="max_image_size_admin" id="max_image_size_admin" value="Y" checked="checked"|cond="$config->max_image_size_admin === 'Y'" />
{$lang->max_image_size_admin}
</label>
</p>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{$lang->image_autoconv}</label>
<div class="x_controls">
<label for="image_autoconv_bmp2jpg" class="x_inline">
<input type="checkbox" name="image_autoconv_bmp2jpg" id="image_autoconv_bmp2jpg" value="Y" checked="checked"|cond="$config->image_autoconv['bmp2jpg']" disabled="disabled"|cond="!function_exists('imagebmp')" />
{$lang->image_autoconv_bmp2jpg}
</label>
<label for="image_autoconv_png2jpg" class="x_inline">
<input type="checkbox" name="image_autoconv_png2jpg" id="image_autoconv_png2jpg" value="Y" checked="checked"|cond="$config->image_autoconv['png2jpg']" disabled="disabled"|cond="!function_exists('imagepng')" />
{$lang->image_autoconv_png2jpg}
</label>
<label for="image_autoconv_webp2jpg" class="x_inline">
<input type="checkbox" name="image_autoconv_webp2jpg" id="image_autoconv_webp2jpg" value="Y" checked="checked"|cond="$config->image_autoconv['webp2jpg']" disabled="disabled"|cond="!function_exists('imagewebp')" />
{$lang->image_autoconv_webp2jpg}
</label>
<select name="image_autoconv_quality" id="image_autoconv_quality" style="width:100px;min-width:100px">
{@ $config->image_autoconv_quality = $config->image_autoconv_quality ?: 75}
<!--@for($q = 50; $q <= 100; $q += 5)-->
<option value="{$q}" selected="selected"|cond="$config->image_autoconv_quality == $q">{$lang->image_resize_quality} {$q}%</option>
<!--@endfor-->
</select>
<p class="x_help-block" style="margin-bottom:10px">{$lang->about_image_autoconv}</p>
<label for="image_autoconv_gif2mp4" class="x_inline">
<input type="checkbox" name="image_autoconv_gif2mp4" id="image_autoconv_gif2mp4" value="Y" checked="checked"|cond="$config->image_autoconv['gif2mp4']" disabled="disabled"|cond="!function_exists('exec')" />
{$lang->image_autoconv_gif2mp4}
</label>
<input type="text" name="ffmpeg_command" id="ffmpeg_command" value="{$config->ffmpeg_command ?: '/usr/bin/ffmpeg'}" placeholder="{$lang->ffmpeg_path}" />
<p class="x_help-block">{$lang->about_image_autoconv_mp4}</p>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{$lang->image_autorotate}</label>
<div class="x_controls">
<label for="image_autorotate_Y" class="x_inline">
<input type="radio" name="image_autorotate" id="image_autorotate_Y" value="Y" checked="checked"|cond="$config->image_autorotate === true" disabled="disabled"|cond="!function_exists('exif_read_data')" />
{$lang->cmd_yes}
</label>
<label for="image_autorotate_N" class="x_inline">
<input type="radio" name="image_autorotate" id="image_autorotate_N" value="N" checked="checked"|cond="$config->image_autorotate !== true" disabled="disabled"|cond="!function_exists('exif_read_data')" />
{$lang->cmd_no}
</label>
<select name="image_autorotate_quality" id="image_autorotate_quality" style="width:100px;min-width:100px">
{@ $config->image_autorotate_quality = $config->image_autorotate_quality ?: 75}
<!--@for($q = 50; $q <= 100; $q += 5)-->
<option value="{$q}" selected="selected"|cond="$config->image_autorotate_quality == $q">{$lang->image_resize_quality} {$q}%</option>
<!--@endfor-->
</select>
<p class="x_help-block">{$lang->about_image_autorotate}</p>
</div>
</div>
<div class="x_control-group">
<label for="allowedFiletypes" class="x_control-label">{$lang->allowed_filetypes}</label>
<div class="x_controls">
<input id="allowedFiletypes" type="text" name="allowed_filetypes" value="{implode(', ', $config->allowed_extensions ?: [])}" />
<input id="allowedFiletypes" type="text" name="allowed_filetypes" value="{implode(', ', $config->allowed_extensions)}" />
<p class="x_help-block">{$lang->about_allowed_filetypes}</p>
</div>
</div>
<section class="section">
<h1>{$lang->image}</h1>
<div class="x_control-group">
<label class="x_control-label">{$lang->image_autoconv}</label>
<div class="x_controls">
<label for="image_autoconv_bmp2jpg">
<input type="checkbox" name="image_autoconv_bmp2jpg" id="image_autoconv_bmp2jpg" value="Y" checked="checked"|cond="$config->image_autoconv['bmp2jpg']" disabled="disabled"|cond="!function_exists('imagebmp')" />
{$lang->image_autoconv_bmp2jpg}
</label>
<label for="image_autoconv_png2jpg">
<input type="checkbox" name="image_autoconv_png2jpg" id="image_autoconv_png2jpg" value="Y" checked="checked"|cond="$config->image_autoconv['png2jpg']" disabled="disabled"|cond="!function_exists('imagepng')" />
{$lang->image_autoconv_png2jpg}
</label>
<label for="image_autoconv_webp2jpg">
<input type="checkbox" name="image_autoconv_webp2jpg" id="image_autoconv_webp2jpg" value="Y" checked="checked"|cond="$config->image_autoconv['webp2jpg']" disabled="disabled"|cond="!function_exists('imagewebp')" />
{$lang->image_autoconv_webp2jpg}
</label>
<p class="x_help-block">{$lang->about_image_autoconv}</p>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{$lang->max_image_size}</label>
<div class="x_controls">
<input type="number" min="0" name="max_image_width" id="max_image_width" value="{$config->max_image_width}" size="7" style="min-width:80px" /> &times;
<input type="number" min="0" name="max_image_height" id="max_image_height" value="{$config->max_image_height}" size="7" style="min-width:80px" /> px &nbsp;
<select name="max_image_size_action" id="max_image_size_action">
<option value="">{$lang->max_image_size_action_nothing}</option>
<option value="block" selected="selected"|cond="$config->max_image_size_action === 'block'">{$lang->max_image_size_action_block}</option>
<option value="resize" selected="selected"|cond="$config->max_image_size_action === 'resize'">{$lang->max_image_size_action_resize}</option>
</select>
<p class="x_help-block">
{$lang->about_max_image_size}
<label for="max_image_size_admin">
<input type="checkbox" name="max_image_size_admin" id="max_image_size_admin" value="Y" checked="checked"|cond="$config->max_image_size_admin === 'Y'" />
{$lang->max_image_size_admin}
</label>
</p>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{$lang->image_quality_adjustment}</label>
<div class="x_controls">
<select name="image_quality_adjustment" style="min-width:80px">
<!--@for($q = 50; $q <= 100; $q += 5)-->
<option value="{$q}" selected="selected"|cond="$config->image_quality_adjustment === $q"><!--@if($q === 100)-->{$lang->original_image_quality}<!--@else-->{$q}%<!--@end--></option>
<!--@endfor-->
</select>
<p class="x_help-block">{$lang->about_image_quality_adjustment}</p>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{$lang->image_autorotate}</label>
<div class="x_controls">
<label for="image_autorotate_Y" class="x_inline">
<input type="radio" name="image_autorotate" id="image_autorotate_Y" value="Y" checked="checked"|cond="$config->image_autorotate === true" disabled="disabled"|cond="!function_exists('exif_read_data')" />
{$lang->cmd_yes}
</label>
<label for="image_autorotate_N" class="x_inline">
<input type="radio" name="image_autorotate" id="image_autorotate_N" value="N" checked="checked"|cond="$config->image_autorotate !== true" disabled="disabled"|cond="!function_exists('exif_read_data')" />
{$lang->cmd_no}
</label>
<p class="x_help-block">{$lang->about_image_autorotate}</p>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{$lang->image_autoconv_gif2mp4}</label>
<div class="x_controls">
<label for="image_autoconv_gif2mp4_Y" class="x_inline">
<input type="radio" name="image_autoconv_gif2mp4" id="image_autoconv_gif2mp4_Y" value="Y" checked="checked"|cond="$config->image_autoconv['gif2mp4'] === true" disabled="disabled"|cond="!function_exists('exec')" />
{$lang->cmd_yes}
</label>
<label for="image_autoconv_gif2mp4_N" class="x_inline">
<input type="radio" name="image_autoconv_gif2mp4" id="image_autoconv_gif2mp4_N" value="N" checked="checked"|cond="$config->image_autoconv['gif2mp4'] !== true" disabled="disabled"|cond="!function_exists('exec')" />
{$lang->cmd_no}
</label>
<p class="x_help-block">{$lang->about_image_autoconv_gif2mp4}</p>
</div>
</div>
</section>
<section class="section">
<h1>{$lang->video}</h1>
<div class="x_control-group">
<label class="x_control-label">{$lang->video_thumbnail}</label>
<div class="x_controls">
<label for="video_thumbnail_Y" class="x_inline">
<input type="radio" name="video_thumbnail" id="video_thumbnail_Y" value="Y" checked="checked"|cond="$config->video_thumbnail === true" disabled="disabled"|cond="!function_exists('exec')" />
{$lang->cmd_yes}
</label>
<label for="video_thumbnail_N" class="x_inline">
<input type="radio" name="video_thumbnail" id="video_thumbnail_N" value="N" checked="checked"|cond="$config->video_thumbnail !== true" disabled="disabled"|cond="!function_exists('exec')" />
{$lang->cmd_no}
</label>
<p class="x_help-block">{$lang->about_video_thumbnail}</p>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{$lang->video_mp4_gif_time}</label>
<div class="x_controls">
<input type="number" min="0" name="video_mp4_gif_time" value="{$config->video_mp4_gif_time}" style="min-width:80px" disabled="disabled"|cond="!function_exists('exec')" /> {$lang->unit_sec}
<p class="x_help-block">{$lang->about_video_mp4_gif_time}</p>
</div>
</div>
</section>
<section class="section">
<h1>FFmpeg</h1>
<div class="x_control-group">
<label class="x_control-label">{$lang->ffmpeg_path}</label>
<div class="x_controls">
<input type="text" name="ffmpeg_command" value="{$config->ffmpeg_command}" />
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{$lang->ffprobe_path}</label>
<div class="x_controls">
<input type="text" name="ffprobe_command" value="{$config->ffprobe_command}" />
</div>
</div>
</section>
<div class="x_clearfix btnArea">
<div class="x_pull-right">
<button type="submit" class="x_btn x_btn-primary">{$lang->cmd_save}</button>