회원 프로필 사진 업로드 시 파일 용량 제한 설정 추가

xpressengine/xe-core#2202

- 기본 값 : 용량 제한하지 않음
- KB 단위로 지정할 수 있으며
- 이미지가 리사이즈 과정을 거치는 경우 리사이즈 된 파일의 용량으로 적용 함
This commit is contained in:
bnu 2018-01-04 17:40:19 +09:00 committed by Kijin Sung
parent 4dede913e4
commit 2119c84b77
4 changed files with 175 additions and 48 deletions

View file

@ -131,19 +131,22 @@ class memberAdminController extends member
$profile_image = $_FILES['profile_image']; $profile_image = $_FILES['profile_image'];
if(is_uploaded_file($profile_image['tmp_name'])) if(is_uploaded_file($profile_image['tmp_name']))
{ {
$oMemberController->insertProfileImage($args->member_srl, $profile_image['tmp_name']); $output = $oMemberController->insertProfileImage($args->member_srl, $profile_image['tmp_name']);
if(!$output->toBool()) return $output;
} }
$image_mark = $_FILES['image_mark']; $image_mark = $_FILES['image_mark'];
if(is_uploaded_file($image_mark['tmp_name'])) if(is_uploaded_file($image_mark['tmp_name']))
{ {
$oMemberController->insertImageMark($args->member_srl, $image_mark['tmp_name']); $output = $oMemberController->insertImageMark($args->member_srl, $image_mark['tmp_name']);
if(!$output->toBool()) return $output;
} }
$image_name = $_FILES['image_name']; $image_name = $_FILES['image_name'];
if (is_uploaded_file($image_name['tmp_name'])) if (is_uploaded_file($image_name['tmp_name']))
{ {
$oMemberController->insertImageName($args->member_srl, $image_name['tmp_name']); $output = $oMemberController->insertImageName($args->member_srl, $image_name['tmp_name']);
if(!$output->toBool()) return $output;
} }
// Clear cache // Clear cache
@ -291,9 +294,9 @@ class memberAdminController extends member
'limit_day_description', 'limit_day_description',
'emailhost_check', 'emailhost_check',
'redirect_url', 'redirect_url',
'profile_image', 'profile_image_max_width', 'profile_image_max_height', 'profile_image', 'profile_image_max_width', 'profile_image_max_height', 'profile_image_max_filesize',
'image_name', 'image_name_max_width', 'image_name_max_height', 'image_name', 'image_name_max_width', 'image_name_max_height', 'image_name_max_filesize',
'image_mark', 'image_mark_max_width', 'image_mark_max_height', 'image_mark', 'image_mark_max_width', 'image_mark_max_height', 'image_mark_max_filesize',
'signature_editor_skin', 'sel_editor_colorset', 'signature_html', 'signature_html_retroact', 'member_allow_fileupload' 'signature_editor_skin', 'sel_editor_colorset', 'signature_html', 'signature_html_retroact', 'member_allow_fileupload'
); );
@ -331,27 +334,33 @@ class memberAdminController extends member
// signupForm // signupForm
global $lang; global $lang;
$signupForm = array(); $signupForm = array();
$items = array('user_id', 'password', 'user_name', 'nick_name', 'email_address', 'homepage', 'blog', 'birthday', 'signature', 'profile_image', 'image_name', 'image_mark', 'profile_image_max_width', 'profile_image_max_height', 'image_name_max_width', 'image_name_max_height', 'image_mark_max_width', 'image_mark_max_height'); $items = array(
'user_id', 'password', 'user_name', 'nick_name', 'email_address', 'homepage', 'blog', 'birthday', 'signature',
'profile_image', 'profile_image_max_width', 'profile_image_max_height', 'profile_image_max_filesize',
'image_name', 'image_name_max_width', 'image_name_max_height', 'image_name_max_filesize',
'image_mark', 'image_mark_max_width', 'image_mark_max_height', 'image_mark_max_filesize',
);
$mustRequireds = array('email_address', 'nick_name', 'password'); $mustRequireds = array('email_address', 'nick_name', 'password');
$extendItems = $oMemberModel->getJoinFormList(); $extendItems = $oMemberModel->getJoinFormList();
foreach($list_order as $key) foreach($list_order as $key)
{ {
$signupItem = new stdClass(); $signupItem = new stdClass();
$signupItem->isIdentifier = ($key == $all_args->identifier); $signupItem->isIdentifier = ($key == $all_args->identifier);
$signupItem->isDefaultForm = in_array($key, $items); $signupItem->isDefaultForm = in_array($key, $items);
$signupItem->name = $key; $signupItem->name = $key;
if(!in_array($key, $items)) $signupItem->title = $key; $signupItem->title = (!in_array($key, $items)) ? $key : $lang->{$key};
else $signupItem->title = $lang->{$key};
$signupItem->mustRequired = in_array($key, $mustRequireds); $signupItem->mustRequired = in_array($key, $mustRequireds);
$signupItem->imageType = (strpos($key, 'image') !== false); $signupItem->imageType = (strpos($key, 'image') !== false);
$signupItem->required = ($all_args->{$key} == 'required') || $signupItem->mustRequired || $signupItem->isIdentifier; $signupItem->required = ($all_args->{$key} == 'required') || $signupItem->mustRequired || $signupItem->isIdentifier;
$signupItem->isUse = in_array($key, $usable_list) || $signupItem->required; $signupItem->isUse = in_array($key, $usable_list) || $signupItem->required;
$signupItem->isPublic = ($all_args->{'is_'.$key.'_public'} == 'Y' && $signupItem->isUse) ? 'Y' : 'N'; $signupItem->isPublic = ($all_args->{'is_'.$key.'_public'} == 'Y' && $signupItem->isUse) ? 'Y' : 'N';
if($signupItem->imageType) if($signupItem->imageType)
{ {
$signupItem->max_width = $all_args->{$key.'_max_width'}; $signupItem->max_width = $all_args->{$key.'_max_width'};
$signupItem->max_height = $all_args->{$key.'_max_height'}; $signupItem->max_height = $all_args->{$key.'_max_height'};
$signupItem->max_filesize = $all_args->{$key.'_max_filesize'};
} }
// set extends form // set extends form

View file

@ -1060,13 +1060,12 @@ class memberController extends member
$logged_info = Context::get('logged_info'); $logged_info = Context::get('logged_info');
if($logged_info->is_admin != 'Y' && $logged_info->member_srl != $member_srl) return $this->stop('msg_not_uploaded_profile_image'); if($logged_info->is_admin != 'Y' && $logged_info->member_srl != $member_srl) return $this->stop('msg_not_uploaded_profile_image');
// Return if member module is set not to use an image name or the user is not an administrator ; // Return if member module is set not to use an image name or the user is not an administrator ;
$oModuleModel = getModel('module'); $oMemberModel = getModel('member');
$config = $oModuleModel->getModuleConfig('member'); $config = $oMemberModel->getMemberConfig();
if($logged_info->is_admin != 'Y' && $config->profile_image != 'Y') return $this->stop('msg_not_uploaded_profile_image'); if($logged_info->is_admin != 'Y' && $config->profile_image != 'Y') return $this->stop('msg_not_uploaded_profile_image');
$this->insertProfileImage($member_srl, $file['tmp_name']); $output = $this->insertProfileImage($member_srl, $file['tmp_name']);
// Page refresh if(!$output->toBool()) return $output;
//$this->setRefreshPage();
$returnUrl = Context::get('success_return_url') ? Context::get('success_return_url') : getNotEncodedUrl('', 'mid', Context::get('mid'), 'act', 'dispMemberModifyInfo'); $returnUrl = Context::get('success_return_url') ? Context::get('success_return_url') : getNotEncodedUrl('', 'mid', Context::get('mid'), 'act', 'dispMemberModifyInfo');
$this->setRedirectUrl($returnUrl); $this->setRedirectUrl($returnUrl);
@ -1084,38 +1083,69 @@ class memberController extends member
{ {
$oMemberModel = getModel('member'); $oMemberModel = getModel('member');
$config = $oMemberModel->getMemberConfig(); $config = $oMemberModel->getMemberConfig();
// Get an image size // Get an image size
$max_width = $config->profile_image_max_width; $max_width = $config->profile_image_max_width;
if(!$max_width) $max_width = "90";
$max_height = $config->profile_image_max_height; $max_height = $config->profile_image_max_height;
if(!$max_height) $max_height = "90"; $max_filesize = $config->profile_image_max_filesize;
// Get a target path to save
$target_path = sprintf('files/member_extra_info/profile_image/%s', getNumberingPath($member_srl)); Context::loadLang(_XE_PATH_ . 'modules/file/lang');
FileHandler::makeDir($target_path);
// Get file information // Get file information
list($width, $height, $type, $attrs) = @getimagesize($target_file); FileHandler::clearStatCache($target_file);
list($width, $height, $type) = @getimagesize($target_file);
if(IMAGETYPE_PNG == $type) $ext = 'png'; if(IMAGETYPE_PNG == $type) $ext = 'png';
elseif(IMAGETYPE_JPEG == $type) $ext = 'jpg'; elseif(IMAGETYPE_JPEG == $type) $ext = 'jpg';
elseif(IMAGETYPE_GIF == $type) $ext = 'gif'; elseif(IMAGETYPE_GIF == $type) $ext = 'gif';
else else
{ {
return; return $this->stop('msg_not_uploaded_profile_image');
} }
FileHandler::removeFilesInDir($target_path); $target_path = sprintf('files/member_extra_info/profile_image/%s', getNumberingPath($member_srl));
FileHandler::makeDir($target_path);
$target_filename = sprintf('%s%d.%s', $target_path, $member_srl, $ext); $target_filename = sprintf('%s%d.%s', $target_path, $member_srl, $ext);
// Convert if the image size is larger than a given size // Convert if the image size is larger than a given size
if($width > $max_width || $height > $max_height) if($width > $max_width || $height > $max_height)
{ {
FileHandler::createImageFile($target_file, $target_filename, $max_width, $max_height, $ext); $temp_filename = sprintf('files/cache/tmp/profile_image_%d.%s', $member_srl, $ext);
FileHandler::createImageFile($target_file, $temp_filename, $max_width, $max_height, $ext);
// 파일 용량 제한
FileHandler::clearStatCache($temp_filename);
$filesize = filesize($temp_filename);
if($max_filesize && $filesize > ($max_filesize * 1024))
{
FileHandler::removeFile($temp_filename);
return $this->stop(implode(' ' , array(
Context::getLang('msg_not_uploaded_profile_image'),
Context::getLang('msg_exceeds_limit_size')
)));
}
FileHandler::removeFilesInDir($target_path);
FileHandler::moveFile($temp_filename, $target_filename);
FileHandler::clearStatCache($target_filename);
} }
else else
{ {
// 파일 용량 제한
$filesize = filesize($target_file);
if($max_filesize && $filesize > ($max_filesize * 1024))
{
return $this->stop(implode(' ' , array(
Context::getLang('msg_not_uploaded_profile_image'),
Context::getLang('msg_exceeds_limit_size')
)));
}
FileHandler::removeFilesInDir($target_path);
@copy($target_file, $target_filename); @copy($target_file, $target_filename);
FileHandler::clearStatCache($target_filename);
} }
return new BaseObject(0, 'success');
} }
/** /**
@ -1135,11 +1165,13 @@ class memberController extends member
$logged_info = Context::get('logged_info'); $logged_info = Context::get('logged_info');
if($logged_info->is_admin != 'Y' && $logged_info->member_srl != $member_srl) return $this->stop('msg_not_uploaded_image_name'); if($logged_info->is_admin != 'Y' && $logged_info->member_srl != $member_srl) return $this->stop('msg_not_uploaded_image_name');
// Return if member module is set not to use an image name or the user is not an administrator ; // Return if member module is set not to use an image name or the user is not an administrator ;
$oModuleModel = getModel('module'); $oMemberModel = getModel('member');
$config = $oModuleModel->getModuleConfig('member'); $config = $oMemberModel->getMemberConfig();
if($logged_info->is_admin != 'Y' && $config->image_name != 'Y') return $this->stop('msg_not_uploaded_image_name'); if($logged_info->is_admin != 'Y' && $config->image_name != 'Y') return $this->stop('msg_not_uploaded_image_name');
$this->insertImageName($member_srl, $file['tmp_name']); $output = $this->insertImageName($member_srl, $file['tmp_name']);
if(!$output->toBool()) return $output;
// Page refresh // Page refresh
//$this->setRefreshPage(); //$this->setRefreshPage();
@ -1157,23 +1189,63 @@ class memberController extends member
*/ */
function insertImageName($member_srl, $target_file) function insertImageName($member_srl, $target_file)
{ {
$oModuleModel = getModel('module'); $oMemberModel = getModel('member');
$config = $oModuleModel->getModuleConfig('member'); $config = $oMemberModel->getMemberConfig();
// Get an image size // Get an image size
$max_width = $config->image_name_max_width; $max_width = $config->image_name_max_width;
if(!$max_width) $max_width = "90";
$max_height = $config->image_name_max_height; $max_height = $config->image_name_max_height;
if(!$max_height) $max_height = "20"; $max_filesize = $config->image_name_max_filesize;
Context::loadLang(_XE_PATH_ . 'modules/file/lang');
// Get a target path to save // Get a target path to save
$target_path = sprintf('files/member_extra_info/image_name/%s/', getNumberingPath($member_srl)); $target_path = sprintf('files/member_extra_info/image_name/%s/', getNumberingPath($member_srl));
FileHandler::makeDir($target_path); FileHandler::makeDir($target_path);
$target_filename = sprintf('%s%d.gif', $target_path, $member_srl); $target_filename = sprintf('%s%d.gif', $target_path, $member_srl);
// Get file information // Get file information
list($width, $height, $type, $attrs) = @getimagesize($target_file); list($width, $height, $type) = @getimagesize($target_file);
// Convert if the image size is larger than a given size or if the format is not a gif // Convert if the image size is larger than a given size or if the format is not a gif
if($width > $max_width || $height > $max_height || $type!=1) FileHandler::createImageFile($target_file, $target_filename, $max_width, $max_height, 'gif'); if($width > $max_width || $height > $max_height || $type!=1)
else @copy($target_file, $target_filename); {
$temp_filename = sprintf('files/cache/tmp/image_name_%d.gif', $member_srl, $ext);
FileHandler::createImageFile($target_file, $temp_filename, $max_width, $max_height, 'gif');
// 파일 용량 제한
FileHandler::clearStatCache($temp_filename);
$filesize = filesize($temp_filename);
if($max_filesize && $filesize > ($max_filesize * 1024))
{
FileHandler::removeFile($temp_filename);
return $this->stop(implode(' ' , array(
Context::getLang('msg_not_uploaded_image_name'),
Context::getLang('msg_exceeds_limit_size')
)));
}
FileHandler::removeFilesInDir($target_path);
FileHandler::moveFile($temp_filename, $target_filename);
FileHandler::clearStatCache($target_filename);
}
else
{
// 파일 용량 제한
$filesize = filesize($target_file);
if($max_filesize && $filesize > ($max_filesize * 1024))
{
return $this->stop(implode(' ' , array(
Context::getLang('msg_not_uploaded_image_name'),
Context::getLang('msg_exceeds_limit_size')
)));
}
FileHandler::removeFilesInDir($target_path);
@copy($target_file, $target_filename);
FileHandler::clearStatCache($target_filename);
}
return new BaseObject(0, 'success');
} }
/** /**
@ -1244,13 +1316,12 @@ class memberController extends member
$logged_info = Context::get('logged_info'); $logged_info = Context::get('logged_info');
if($logged_info->is_admin != 'Y' && $logged_info->member_srl != $member_srl) return $this->stop('msg_not_uploaded_image_mark'); if($logged_info->is_admin != 'Y' && $logged_info->member_srl != $member_srl) return $this->stop('msg_not_uploaded_image_mark');
// Membership in the images mark the module using the ban was set by an administrator or return; // Membership in the images mark the module using the ban was set by an administrator or return;
$oModuleModel = getModel('module'); $oMemberModel = getModel('member');
$config = $oModuleModel->getModuleConfig('member'); $config = $oMemberModel->getMemberConfig();
if($logged_info->is_admin != 'Y' && $config->image_mark != 'Y') return $this->stop('msg_not_uploaded_image_mark'); if($logged_info->is_admin != 'Y' && $config->image_mark != 'Y') return $this->stop('msg_not_uploaded_image_mark');
$this->insertImageMark($member_srl, $file['tmp_name']); $this->insertImageMark($member_srl, $file['tmp_name']);
// Page refresh if(!$output->toBool()) return $output;
//$this->setRefreshPage();
$returnUrl = Context::get('success_return_url') ? Context::get('success_return_url') : getNotEncodedUrl('', 'mid', Context::get('mid'), 'act', 'dispMemberModifyInfo'); $returnUrl = Context::get('success_return_url') ? Context::get('success_return_url') : getNotEncodedUrl('', 'mid', Context::get('mid'), 'act', 'dispMemberModifyInfo');
$this->setRedirectUrl($returnUrl); $this->setRedirectUrl($returnUrl);
@ -1266,13 +1337,15 @@ class memberController extends member
*/ */
function insertImageMark($member_srl, $target_file) function insertImageMark($member_srl, $target_file)
{ {
$oModuleModel = getModel('module'); $oMemberModel = getModel('member');
$config = $oModuleModel->getModuleConfig('member'); $config = $oMemberModel->getMemberConfig();
// Get an image size // Get an image size
$max_width = $config->image_mark_max_width; $max_width = $config->image_mark_max_width;
if(!$max_width) $max_width = "20";
$max_height = $config->image_mark_max_height; $max_height = $config->image_mark_max_height;
if(!$max_height) $max_height = "20"; $max_filesize = $config->image_mark_max_filesize;
Context::loadLang(_XE_PATH_ . 'modules/file/lang');
$target_path = sprintf('files/member_extra_info/image_mark/%s/', getNumberingPath($member_srl)); $target_path = sprintf('files/member_extra_info/image_mark/%s/', getNumberingPath($member_srl));
FileHandler::makeDir($target_path); FileHandler::makeDir($target_path);
@ -1281,8 +1354,45 @@ class memberController extends member
// Get file information // Get file information
list($width, $height, $type, $attrs) = @getimagesize($target_file); list($width, $height, $type, $attrs) = @getimagesize($target_file);
if($width > $max_width || $height > $max_height || $type!=1) FileHandler::createImageFile($target_file, $target_filename, $max_width, $max_height, 'gif'); if($width > $max_width || $height > $max_height || $type!=1)
else @copy($target_file, $target_filename); {
$temp_filename = sprintf('files/cache/tmp/image_mark_%d.gif', $member_srl);
FileHandler::createImageFile($target_file, $temp_filename, $max_width, $max_height, 'gif');
// 파일 용량 제한
FileHandler::clearStatCache($temp_filename);
$filesize = filesize($temp_filename);
if($max_filesize && $filesize > ($max_filesize * 1024))
{
FileHandler::removeFile($temp_filename);
return $this->stop(implode(' ' , array(
Context::getLang('msg_not_uploaded_group_image_mark'),
Context::getLang('msg_exceeds_limit_size')
)));
}
FileHandler::removeFilesInDir($target_path);
FileHandler::moveFile($temp_filename, $target_filename);
FileHandler::clearStatCache($target_filename);
}
else
{
$filesize = filesize($target_file);
if($max_filesize && $filesize > ($max_filesize * 1024))
{
FileHandler::removeFile($target_file);
return $this->stop(implode(' ' , array(
Context::getLang('msg_not_uploaded_group_image_mark'),
Context::getLang('msg_exceeds_limit_size')
)));
}
FileHandler::removeFilesInDir($target_path);
@copy($target_file, $target_filename);
FileHandler::clearStatCache($target_filename);
}
return new BaseObject(0, 'success');
} }
/** /**

View file

@ -60,12 +60,17 @@ class memberModel extends member
} }
if(!$config->webmaster_name) $config->webmaster_name = 'webmaster'; if(!$config->webmaster_name) $config->webmaster_name = 'webmaster';
if(!$config->image_name_max_width) $config->image_name_max_width = 90; if(!$config->image_name_max_width) $config->image_name_max_width = 90;
if(!$config->image_name_max_height) $config->image_name_max_height = 20; if(!$config->image_name_max_height) $config->image_name_max_height = 20;
if(!$config->image_name_max_filesize) $config->image_name_max_filesize = null;
if(!$config->image_mark_max_width) $config->image_mark_max_width = 20; if(!$config->image_mark_max_width) $config->image_mark_max_width = 20;
if(!$config->image_mark_max_height) $config->image_mark_max_height = 20; if(!$config->image_mark_max_height) $config->image_mark_max_height = 20;
if(!$config->image_mark_max_filesize) $config->image_mark_max_filesize = null;
if(!$config->profile_image_max_width) $config->profile_image_max_width = 90; if(!$config->profile_image_max_width) $config->profile_image_max_width = 90;
if(!$config->profile_image_max_height) $config->profile_image_max_height = 90; if(!$config->profile_image_max_height) $config->profile_image_max_height = 90;
if(!$config->profile_image_max_filesize) $config->profile_image_max_filesize = null;
if(!$config->skin) $config->skin = 'default'; if(!$config->skin) $config->skin = 'default';
if(!$config->colorset) $config->colorset = 'white'; if(!$config->colorset) $config->colorset = 'white';
if(!$config->editor_skin || $config->editor_skin == 'default') $config->editor_skin = 'ckeditor'; if(!$config->editor_skin || $config->editor_skin == 'default') $config->editor_skin = 'ckeditor';

View file

@ -1,5 +1,6 @@
<include target="header.html" /> <include target="header.html" />
<load target="js/signup_config.js" /> <load target="js/signup_config.js" />
<load target="../../file/lang/lang.xml" />
<load target="../../editor/tpl/js/editor_module_config.js" /> <load target="../../editor/tpl/js/editor_module_config.js" />
<script> <script>
xe.lang.msg_delete_extend_form = '{$lang->msg_delete_extend_form}'; xe.lang.msg_delete_extend_form = '{$lang->msg_delete_extend_form}';
@ -139,11 +140,13 @@
<td class="nowr"> <td class="nowr">
<label for="{$item->name}_re" class="x_inline"><input type="radio" id="{$item->name}_re" name="{$item->name}" value="required" checked="checked"|cond="$item->mustRequired || $item->required" disabled="disabled"|cond="$item->mustRequired || !$item->isUse" /> {$lang->cmd_required}</label> <label for="{$item->name}_re" class="x_inline"><input type="radio" id="{$item->name}_re" name="{$item->name}" value="required" checked="checked"|cond="$item->mustRequired || $item->required" disabled="disabled"|cond="$item->mustRequired || !$item->isUse" /> {$lang->cmd_required}</label>
<label for="{$item->name}_op" class="x_inline"><input type="radio" id="{$item->name}_op" name="{$item->name}" value="option" checked="checked"|cond="!$item->mustRequired && ($item->isUse && !$item->required)" disabled="disabled"|cond="$item->mustRequired || !$item->isUse" /> {$lang->cmd_optional}</label> <label for="{$item->name}_op" class="x_inline"><input type="radio" id="{$item->name}_op" name="{$item->name}" value="option" checked="checked"|cond="!$item->mustRequired && ($item->isUse && !$item->required)" disabled="disabled"|cond="$item->mustRequired || !$item->isUse" /> {$lang->cmd_optional}</label>
<div cond="$item->imageType" class="_subItem" style="display:none"|cond="!$item->isUse"> <div cond="$item->imageType" class="_subItem" style="display:none"|cond="!$item->isUse">
<label for="{$item->name}_max_width" class="x_inline">{$lang->cmd_image_max_width} <input type="number" min="1" name="{$item->name}_max_width" id="{$item->name}_max_width" value="{$item->max_width}" /> px</label> <label for="{$item->name}_max_width">{$lang->cmd_image_max_width}: <input type="number" min="1" name="{$item->name}_max_width" id="{$item->name}_max_width" value="{$item->max_width}" /> px</label>
/ <label for="{$item->name}_max_height">{$lang->cmd_image_max_height}: <input type="number" min="1" name="{$item->name}_max_height" id="{$item->name}_max_height" value="{$item->max_height}" /> px</label>
<label for="{$item->name}_max_height" class="x_inline">{$lang->cmd_image_max_height} <input type="number" min="1" name="{$item->name}_max_height" id="{$item->name}_max_height" value="{$item->max_height}" /> px</label> <label for="{$item->name}_max_filesize">{$lang->allowed_filesize}: <input type="number" min="1" name="{$item->name}_max_filesize" id="{$item->name}_max_filesize" value="{$item->max_filesize}" /> KB</label>
</div> </div>
<div cond="$item->name == 'signature'" class="_subItem" style="display:none;padding-top:5px"|cond="!$item->isUse"> <div cond="$item->name == 'signature'" class="_subItem" style="display:none;padding-top:5px"|cond="!$item->isUse">
<select id="signature_editor" name="signature_editor_skin" onchange="getEditorSkinColorList(this.value)"> <select id="signature_editor" name="signature_editor_skin" onchange="getEditorSkinColorList(this.value)">
<!--@foreach($editor_skin_list as $editor_skin)--> <!--@foreach($editor_skin_list as $editor_skin)-->