Merge branch 'rhymix:master' into master

This commit is contained in:
Lastorder 2025-03-03 10:47:47 +09:00 committed by GitHub
commit e5b729f8e9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
152 changed files with 2348 additions and 792 deletions

View file

@ -87,6 +87,8 @@ $lang->verify_by_sms_confirm = 'Confirm';
$lang->verify_by_sms_message = 'Your verification code is %s.';
$lang->verify_by_sms_code_sent = 'A verification code has been sent to the number you entered.';
$lang->verify_by_sms_code_incorrect = 'The code you entered is incorrect.';
$lang->verify_by_sms_code_too_many_tries = 'Too many incorrect attempts. Please request a new code.';
$lang->verify_by_sms_code_expired = 'The code has expired. Please request a new code.';
$lang->verify_by_sms_code_confirmed = 'Your phone number has been confirmed.';
$lang->verify_by_sms_incomplete = 'Your phone number has not been verified. Please go through the verification process first.';
$lang->verify_by_sms_error = 'This website cannot send SMS.';

View file

@ -87,6 +87,8 @@ $lang->verify_by_sms_confirm = '인증번호 확인';
$lang->verify_by_sms_message = '인증번호는 %s입니다.';
$lang->verify_by_sms_code_sent = '인증번호가 SMS로 발송되었습니다.';
$lang->verify_by_sms_code_incorrect = '인증번호가 올바르지 않습니다.';
$lang->verify_by_sms_code_too_many_tries = '여러 번 틀려서 인증번호가 초기화됩니다. 다시 인증해 주세요.';
$lang->verify_by_sms_code_expired = '인증번호의 유효기간이 만료되었습니다. 다시 인증해 주세요.';
$lang->verify_by_sms_code_confirmed = '인증이 완료되었습니다.';
$lang->verify_by_sms_incomplete = '전화번호가 인증되지 않았습니다. 인증 과정을 거쳐 주십시오.';
$lang->verify_by_sms_error = 'SMS를 발송할 수 없습니다.';

View file

@ -26,7 +26,7 @@
<fieldset class="sn">
<ul>
<li>
<li cond="$identifierForm->name !== 'phone_number'">
<label for="identifierForm">{$identifierForm->title} <em style="color:red">*</em></label>
<input id="identifierForm" type="text" name="{$identifierForm->name}" value="{$identifierForm->value}" disabled="disabled" />
<input type="hidden" name="{$identifierForm->name}" value="{$identifierForm->value}" />
@ -78,4 +78,4 @@
return false;});
});
})(jQuery);
</script>
</script>

View file

@ -31,7 +31,7 @@
</div>
</div>
<ul>
<li>
<li cond="$identifierForm->name !== 'phone_number'">
<label for="{$identifierForm->name}">{$identifierForm->title} <em style="color:red">*</em></label>
<input type="text"|cond="$identifierForm->name!='email_address'" type="email"|cond="$identifierForm->name=='email_address'" name="{$identifierForm->name}" id="{$identifierForm->name}" value="" />
</li>

View file

@ -123,14 +123,20 @@ class MemberAdminController extends Member
}
// remove whitespace
$checkInfos = array('user_id', 'user_name', 'nick_name', 'email_address');
foreach($checkInfos as $val)
foreach(['user_id', 'nick_name', 'email_address'] as $val)
{
if(isset($args->{$val}))
{
$args->{$val} = preg_replace('/[\pZ\pC]+/u', '', utf8_clean(html_entity_decode($args->{$val})));
}
}
foreach(['user_name'] as $val)
{
if(isset($args->{$val}))
{
$args->{$val} = utf8_normalize_spaces(utf8_clean(html_entity_decode($args->{$val})));
}
}
// 실제로 디비쿼리시 빈값이 없다면 해당 쿼리를 무시하고 업데이트 하기 때문에 메모의 내용이 삭제가 되지 않습니다.
if(!isset($args->description))
@ -666,7 +672,33 @@ class MemberAdminController extends Member
$args->mskin = 'default';
}
// Update member module config
$output = $oModuleController->updateModuleConfig('member', $args);
if (!$output->toBool())
{
return $output;
}
// Sync member mid info with module config
$config = MemberModel::getMemberConfig();
if ($config->mid)
{
$module_info = ModuleModel::getModuleInfoByMid($config->mid);
if ($module_info->module === 'member')
{
$module_info->layout_srl = $args->layout_srl ?? -1;
$module_info->mlayout_srl = $args->mlayout_srl ?? -1;
$module_info->skin = $args->skin;
$module_info->mskin = $args->mskin;
$module_info->is_skin_fix = str_starts_with($module_info->skin, '/') ? 'N' : 'Y';
$module_info->is_mskin_fix = str_starts_with($module_info->mskin, '/') ? 'N' : 'Y';
$output = ModuleController::getInstance()->updateModule($module_info);
if (!$output->toBool())
{
return $output;
}
}
}
// default setting end
$this->setMessage('success_updated');
@ -1357,7 +1389,7 @@ class MemberAdminController extends Member
}
$args->group_srl = !empty($args->group_srl) ? $args->group_srl : getNextSequence();
$args->list_order = $args->list_order ?? $args->group_srl;
$args->title = escape($args->title);
$args->title = escape($args->title, false, true);
$args->description = escape($args->description);
$output = executeQuery('member.insertGroup', $args);
@ -1408,7 +1440,7 @@ class MemberAdminController extends Member
$output = executeQuery('member.updateGroupDefaultClear', $args);
if(!$output->toBool()) return $output;
}
$args->title = isset($args->title) ? escape($args->title) : null;
$args->title = isset($args->title) ? escape($args->title, false, true) : null;
$args->description = isset($args->description) ? escape($args->description) : null;
$output = executeQuery('member.updateGroup', $args);

View file

@ -58,9 +58,12 @@ class MemberAdminView extends Member
// retrieve group list
$this->group_list = $oMemberModel->getGroups();
foreach ($this->group_list as $group)
if ($this->act !== 'dispMemberAdminGroupList')
{
$group->title = Context::replaceUserLang($group->title, true);
foreach ($this->group_list as $group)
{
$group->title = Context::replaceUserLang($group->title, true);
}
}
Context::set('group_list', $this->group_list);
@ -455,18 +458,19 @@ class MemberAdminView extends Member
}
}
$identifier = array_first($member_config->identifiers);
$identifierForm = new stdClass;
$identifierForm->title = lang($identifier);
$identifierForm->name = $identifier;
$identifierForm->value = $member_info->$identifier;
Context::set('identifierForm', $identifierForm);
if ($member_info->limit_date < date('Ymd'))
{
$member_info->limit_date = '';
}
if (Context::get('member_srl'))
{
Context::setBrowserTitle(lang('member.msg_update_member'));
}
else
{
Context::setBrowserTitle(lang('member.msg_new_member'));
}
$this->setTemplateFile('insert_member');
}
@ -508,7 +512,11 @@ class MemberAdminView extends Member
foreach($member_config->signupForm as $formInfo)
{
if(!$formInfo->isUse || (in_array($formInfo->name, $identifiers) && $formInfo->name === array_first($identifiers)) || $formInfo->name == 'password')
if(!$formInfo->isUse || ($formInfo->name == 'password' && !$isAdmin))
{
continue;
}
if((in_array($formInfo->name, $identifiers) && $formInfo->name === array_first($identifiers)) && !$isAdmin)
{
continue;
}
@ -675,6 +683,16 @@ class MemberAdminView extends Member
$input->value = $memberInfo[$formInfo->name] ?? '';
$inputTag = $input->getFormHTML();
}
else if($formInfo->name == 'password')
{
$formTag->type = 'password';
$input = new Rhymix\Modules\Extravar\Models\Value(0, 1, '', 'password');
$input->parent_type = 'member';
$input->input_name = $formInfo->name;
$input->input_id = $formInfo->name;
$input->value = '';
$inputTag = $input->getFormHTML();
}
else
{
if($formInfo->name === 'nick_name' && ($member_config->allow_nickname_change ?? 'Y') === 'N' && !$isAdmin && !$isSignup)

View file

@ -796,14 +796,20 @@ class MemberController extends Member
}
// remove whitespace
$checkInfos = array('user_id', 'user_name', 'nick_name', 'email_address');
foreach($checkInfos as $val)
foreach(['user_id', 'nick_name', 'email_address'] as $val)
{
if(isset($args->{$val}))
{
$args->{$val} = preg_replace('/[\pZ\pC]+/u', '', utf8_clean(html_entity_decode($args->{$val})));
}
}
foreach(['user_name'] as $val)
{
if(isset($args->{$val}))
{
$args->{$val} = utf8_normalize_spaces(utf8_clean(html_entity_decode($args->{$val})));
}
}
// Check symbols in nickname
if($config->nickname_symbols === 'N')
@ -867,12 +873,24 @@ class MemberController extends Member
$this->putSignature($args->member_srl, $signature);
// Log-in
if($config->enable_confirm != 'Y')
if ($config->enable_confirm != 'Y')
{
$output = $this->doLogin($args->{$config->identifier});
if(!$output->toBool()) {
if($output->error == -9)
if (isset($config->identifiers) && is_array($config->identifiers))
{
$identifier = array_first($config->identifiers);
}
else
{
$identifier = $config->identifier ?? 'user_id';
}
$output = $this->doLogin($args->{$identifier});
if (!$output->toBool())
{
if ($output->error == -9)
{
$output->error = -11;
}
return $this->setRedirectUrl(getUrl('', 'act', 'dispMemberLoginForm'), $output);
}
}
@ -1080,14 +1098,20 @@ class MemberController extends Member
$args->extra_vars = serialize($extra_vars);
// remove whitespace
$checkInfos = array('user_id', 'user_name', 'nick_name', 'email_address');
foreach($checkInfos as $val)
foreach(['user_id', 'nick_name', 'email_address'] as $val)
{
if(isset($args->{$val}))
{
$args->{$val} = preg_replace('/[\pZ\pC]+/u', '', utf8_clean(html_entity_decode($args->{$val})));
}
}
foreach(['user_name'] as $val)
{
if(isset($args->{$val}))
{
$args->{$val} = utf8_normalize_spaces(utf8_clean(html_entity_decode($args->{$val})));
}
}
// Check if nickname change is allowed
if(isset($config->allow_nickname_change) && $config->allow_nickname_change === 'N')
@ -3772,6 +3796,8 @@ class MemberController extends Member
'country' => $phone_country,
'number' => $phone_number,
'code' => $is_special ? intval($config->special_phone_code) : $code,
'time' => time(),
'count' => 0,
'status' => false,
);
@ -3820,10 +3846,25 @@ class MemberController extends Member
}
$code = intval($code);
if(!isset($_SESSION['verify_by_sms']) || $_SESSION['verify_by_sms']['code'] !== $code)
if(!isset($_SESSION['verify_by_sms']))
{
throw new Rhymix\Framework\Exception('verify_by_sms_code_incorrect');
}
if (isset($_SESSION['verify_by_sms']['count']) && $_SESSION['verify_by_sms']['count'] >= 10)
{
unset($_SESSION['verify_by_sms']);
throw new Rhymix\Framework\Exception('verify_by_sms_code_too_many_tries');
}
if (isset($_SESSION['verify_by_sms']['time']) && $_SESSION['verify_by_sms']['time'] < time() - 600)
{
unset($_SESSION['verify_by_sms']);
throw new Rhymix\Framework\Exception('verify_by_sms_code_expired');
}
if ($_SESSION['verify_by_sms']['code'] !== $code)
{
$_SESSION['verify_by_sms']['count']++;
throw new Rhymix\Framework\Exception('verify_by_sms_code_incorrect');
}
$_SESSION['verify_by_sms']['status'] = true;
return new BaseObject(0, 'verify_by_sms_code_confirmed');

View file

@ -19,7 +19,7 @@
<input type="hidden" name="signature" value="{escape($member_info->signature)}" />
<input type="hidden" name="page" value="{$page}" />
<input type="hidden" name="xe_validator_id" value="modules/member/skins/default/1" />
<div class="control-group">
<div class="control-group" cond="$identifierForm->name !== 'phone_number'">
<label for="{$identifierForm->name}" class="control-label"><em style="color:red">*</em> {$identifierForm->title}</label>
<div class="controls">
<input type="hidden" name="{$identifierForm->name}" value="{$identifierForm->value}" />

View file

@ -27,7 +27,7 @@
</label>
</div>
</div>
<div class="control-group">
<div class="control-group" cond="$identifierForm->name !== 'phone_number'">
<label for="{$identifierForm->name}" class="control-label"><em style="color:red">*</em> {$identifierForm->title}</label>
<div class="controls">
<input type="text"|cond="$identifierForm->name!='email_address'" type="email"|cond="$identifierForm->name=='email_address'" name="{$identifierForm->name}" id="{$identifierForm->name}" value="" required />

View file

@ -5,13 +5,16 @@
xe.lang.deleteImageMark = '{$lang->msg_delete_extend_form}';
xe.lang.deleteImageName = '{$lang->msg_delete_extend_form}';
</script>
<div class="x_page-header">
<h1 cond="$member_srl">{$lang->msg_update_member}</h1>
<h1 cond="!$member_srl">{$lang->msg_new_member}</h1>
</div>
<div cond="$XE_VALIDATOR_MESSAGE && $XE_VALIDATOR_ID == 'modules/member/tpl/1'" class="message {$XE_VALIDATOR_MESSAGE_TYPE}">
<p>{$XE_VALIDATOR_MESSAGE}</p>
</div>
<form action="./" class="x_form-horizontal" ruleset="insertAdminMember" method="post" enctype="multipart/form-data">
<input type="hidden" name="module" value="member" />
<input type="hidden" name="act" value="procMemberAdminInsert" />
@ -20,40 +23,26 @@
<input type="hidden" name="success_return_url" value="{getUrl('act', $act)}" cond="$member_srl" />
<input type="hidden" name="success_return_url" value="{getUrl('act', 'dispMemberAdminList')}" cond="!$member_srl" />
<input type="hidden" name="xe_validator_id" value="modules/member/tpl/1" />
<div cond="$member_srl" class="x_control-group">
<label class="x_control-label" for="identifierForm"><em style="color:red">*</em> {$identifierForm->title}</label>
<div class="x_controls">
<input type="hidden" name="{$identifierForm->name}" value="{$identifierForm->value}" />
<input id="identifierForm" type="email" name="{$identifierForm->name}" value="{$identifierForm->value}" disabled="disabled" />
<!--@foreach($formTags as $formTag)-->
<div class="x_control-group">
<label class="x_control-label" for="{$formTag->name}">{$formTag->title}</label>
<div class="x_controls">
<!--@if($formTag->name === 'password')-->
<!--@if($member_srl)-->
<input id="password" type="password" name="reset_password" value="" autocomplete="off" />
<!--@else-->
<input id="password" type="password" name="password" value="" autocomplete="off" />
<!--@endif-->
<!--@elseif($formTag->name === 'signature')-->
{$editor|noescape}
<!--@else-->
{$formTag->inputTag}
<!--@endif-->
</div>
</div>
</div>
<div cond="!$member_srl" class="x_control-group">
<label class="x_control-label" for="identifierForm"><em style="color:red">*</em> {$identifierForm->title}</label>
<div class="x_controls">
<input id="identifierForm" type="text" name="{$identifierForm->name}" value="" />
</div>
</div>
<div cond="$member_srl" class="x_control-group">
<label class="x_control-label" for="password"><em style="color:red">*</em> {$lang->password}</label>
<div class="x_controls">
<input id="password" type="password" name="reset_password" value="" autocomplete="off" />
</div>
</div>
<div cond="!$member_srl" class="x_control-group">
<label class="x_control-label" for="password"><em style="color:red">*</em> {$lang->password}</label>
<div class="x_controls">
<input id="password" type="text" name="password" value="" autocomplete="off" />
</div>
</div>
<div loop="$formTags=>$formTag" class="x_control-group">
<label class="x_control-label" for="{$formTag->name}">{$formTag->title}</label>
<div class="x_controls" cond="$formTag->name != 'signature'">{$formTag->inputTag}</div>
<div class="x_controls" cond="$formTag->name =='signature'">{$editor|noescape}</div>
</div>
<style scoped>
.xpress-editor>#smart_content,
.xpress-editor>#smart_content>.tool{clear:none}
</style>
<!--@endforeach-->
<div class="x_control-group">
<label class="x_control-label">{$lang->allow_mailing}</label>
<div class="x_controls">
@ -61,6 +50,7 @@
<label class="x_inline" for="mailingNo"><input type="radio" name="allow_mailing" id="mailingNo" value="N" checked="checked"|cond="$member_info->allow_mailing != 'Y'" > {$lang->cmd_no}</label>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{$lang->allow_message}</label>
<div class="x_controls">
@ -69,6 +59,7 @@
</block>
</div>
</div>
<div class="x_control-group div_status" cond="$member_srl">
<label class="x_control-label">{$lang->status}</label>
<div class="x_controls">
@ -77,6 +68,7 @@
<label class="x_inline" for="status_unauthed"><input type="radio" name="status" id="status_unauthed" value="UNAUTHED" checked="checked"|cond="$member_info->status == 'UNAUTHED' && $member_info->member_srl != $logged_info->member_srl" disabled="disabled"|cond="$member_info->member_srl == $logged_info->member_srl" /> {$lang->member_unauthenticated}</label>
</div>
</div>
<div class="x_control-group div_refused_reason">
<label class="x_control-label">{$lang->refused_reason}</label>
<div class="x_controls">
@ -84,6 +76,7 @@
<span class="x_help-inline">{$lang->about_refused_reason}</span>
</div>
</div>
<div class="x_control-group" cond="$member_srl">
<label class="x_control-label" for="until">{$lang->limit_date}</label>
<div class="x_controls">
@ -93,6 +86,7 @@
<span class="x_help-inline">{$lang->about_limit_date}</span>
</div>
</div>
<div class="x_control-group div_limited_reason">
<label class="x_control-label">{$lang->limited_reason}</label>
<div class="x_controls">
@ -100,6 +94,7 @@
<span class="x_help-inline">{$lang->about_limited_reason}</span>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{$lang->is_admin}</label>
<div class="x_controls">
@ -107,6 +102,7 @@
<label class="x_inline" for="not_admin"><input type="radio" name="is_admin" id="not_admin" value="N" checked="checked"|cond="$member_info->is_admin != 'Y'" disabled="disabled"|cond="$member_info->member_srl == $logged_info->member_srl"> {$lang->cmd_no}</label>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label" for="description">{$lang->description}</label>
<div class="x_controls">
@ -114,6 +110,7 @@
<span class="x_help-inline">{$lang->about_member_description}</span>
</div>
</div>
<div class="x_control-group" cond="$member_srl">
<label class="x_control-label">{$lang->signup_date}</label>
<div class="x_controls">
@ -123,6 +120,7 @@
<!--@end-->
</div>
</div>
<div class="x_control-group" cond="$member_srl">
<label class="x_control-label">{$lang->last_login}</label>
<div class="x_controls">
@ -132,6 +130,7 @@
<!--@end-->
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{$lang->member_group}</label>
<div class="x_controls">
@ -141,11 +140,14 @@
</label>
</div>
</div>
<div class="x_clearfix btnArea">
<span class="x_pull-left" cond="$member_srl"><button class="x_btn" type="button" onclick="history.go(-1)">{$lang->cmd_cancel}</button></span>
<span class="x_pull-right"><input class="x_btn x_btn-primary" type="submit" value="{$lang->cmd_save}" /></span>
</div>
</form>
<script>
(function($){
$(function(){