고수님들 ㅠㅠ 포인트선물하기 기능인데 아이디가 아닌 휴대폰으로 하고싶습니다
본문
그누보드 기반인데 반는 아이디로 되어있는 상태야 내가 원하는건 그게 아니라 받는 아이디 대체 회원의 휴대폰번호 입력해서 회원조회후 포인트 선물되게 해줘 아래 는 현재 적용된 소스야
point_gift.skin.php
<?php
if (!defined('_GNUBOARD_')) exit; // 개별 페이지 접근 불가
// add_stylesheet('css 구문', 출력순서); 숫자가 작을 수록 먼저 출력됨
add_stylesheet('<link rel="stylesheet" href="'.$member_skin_url.'/style.css?ver='.G5_TIME_YMDHIS.'">', 0);
add_stylesheet('<link rel="stylesheet" href="'.G5_THEME_URL.'/rb.css/point.css?ver='.G5_TIME_YMDHIS.'" />', 0);
if(isset($pnt['pnt_gift_use']) && $pnt['pnt_gift_use'] == 1) {
}
$message = '';
$message_class = '';
// 포인트 선물 처리
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['gift_user'])) {
$gift_user = trim($_POST['gift_user'] ?? '');
$gift_point = intval($_POST['gift_point'] ?? 0);
$gift_message = trim($_POST['gift_message'] ?? '');
$min_point = 10000; // 최소 포인트
$fee_rate = 0.05; // 수수료 비율
if (empty($gift_user)) {
$message = '받는 회원 아이디를 입력해주세요.';
$message_class = 'error';
} elseif ($gift_point < $min_point) {
$message = '최소 10,000P 이상의 포인트를 선물해야 합니다.';
$message_class = 'error';
} else {
$receiver = get_member($gift_user);
if (!$receiver['mb_id']) {
$message = '존재하지 않는 회원입니다.';
$message_class = 'error';
} elseif ($receiver['mb_id'] === $member['mb_id']) {
$message = '자신에게 포인트를 선물할 수 없습니다.';
$message_class = 'error';
} else {
$fee = floor($gift_point * $fee_rate);
$total_deduction = $gift_point + $fee;
if ($member['mb_point'] < $total_deduction) {
$message = '포인트가 부족합니다.';
$message_class = 'error';
} else {
// 포인트 차감 및 적립
insert_point($member['mb_id'], -$total_deduction, "{$receiver['mb_nick']}님에게 {$gift_point}P 선물 (수수료: {$fee}P)", '@gift', $member['mb_id'], uniqid());
insert_point($receiver['mb_id'], $gift_point, "{$member['mb_nick']}님으로부터 {$gift_point}P 선물 받음", '@gift', $receiver['mb_id'], uniqid());
insert_point('wadmin', $fee, "{$member['mb_id']}님으로부터 수수료 적립 ({$fee}P)", '@gift_fee', 'wadmin', uniqid());
// 쪽지 발송
$memo_subject = "{$member['mb_nick']}님으로부터 포인트 선물 도착!";
$memo_content = "{$member['mb_nick']}님으로부터 {$gift_point}P 포인트를 선물 받았습니다.\n";
if (!empty($gift_message)) {
$memo_content .= "메시지: {$gift_message}\n";
}
sql_query("INSERT INTO {$g5['memo_table']} (me_recv_mb_id, me_send_mb_id, me_send_datetime, me_read_datetime, me_memo)
VALUES ('{$receiver['mb_id']}', '{$member['mb_id']}', '" . G5_TIME_YMDHIS . "', '', '{$memo_subject}\n\n{$memo_content}')");
// PRG 패턴 적용: 성공 메시지와 함께 리다이렉트
set_session('gift_success_message', '? 포인트를 성공적으로 선물했습니다!');
header("Location: {$_SERVER['REQUEST_URI']}");
exit;
}
}
}
}
// PRG 패턴으로 리다이렉트 후 성공 메시지 표시
if (get_session('gift_success_message')) {
$message = get_session('gift_success_message');
$message_class = 'success';
set_session('gift_success_message', ''); // 메시지 세션 초기화
}
?>
<div id="point" class="new_win">
<h1 id="win_title"><?php echo $g5['title']; ?></h1>
<?php if (!empty($message)) { ?>
<div class="alert_message <?php echo $message_class; ?>">
<strong><?php echo $message; ?></strong>
</div>
<?php } ?>
<form name="fgiftform" method="post" onsubmit="return fgiftform_submit(this);">
<div class="new_win_con2">
<ul class="win_ul">
<li class=""><a href="<?php echo G5_URL ?>/rb/point.php">보유포인트</a></li>
<?php if(isset($pnt['pnt_add_use']) && $pnt['pnt_add_use'] == 1) { ?>
<li class=""><a href="<?php echo G5_URL ?>/rb/point.php?types=add">포인트충전</a></li>
<?php } ?>
<?php if(isset($pnt['pnt_acc_use']) && $pnt['pnt_acc_use'] == 1) { ?>
<li class=""><a href="<?php echo G5_URL ?>/rb/point.php?types=acc">포인트출금</a></li>
<?php } ?>
<li class=""><a href="<?php echo G5_URL ?>/rb/point.php?types=gift">포인트선물</a></li>
<div class="cb"></div>
</ul>
<ul class="point_all">
<li class="full_li">
보유포인트
<span><?php echo number_format($member['mb_point']); ?> P</span>
</li>
</ul>
<div class="point_add">
<div class="rb_inp_wrap new_bbs_border_wrap">
<ul>
<li>
<h6 class="bbs_sub_titles font-B mb-5">받는 회원 아이디</h6>
<label class="helps">선물을 받을 회원 아이디를 입력하세요.</label>
<div class="radio_gap">
<input type="text" name="gift_user" value="" id="gift_user" class="input required w40 main_rb_bordercolor main_color font-B" placeholder="받는 회원 아이디" required>
<button type="button" id="check_user_btn" onclick="checkUser();" class="check_user_btn">확인</button>
</div>
<div id="user_check_result" class="user_check_result"></div>
</li>
<li class="mt-20">
<h6 class="bbs_sub_titles font-B mb-5">선물할 포인트</h6>
<label class="helps">선물할 포인트를 입력하세요. <span class="color-000">(최소 10,000P)</span></label>
<div class="radio_gap">
<input type="number" name="gift_point" value="" id="gift_point" class="input required w40 main_rb_bordercolor main_color font-B" placeholder="포인트 입력" required> <span class="font-B">P</span>
</div>
</li>
<li class="mt-20">
<h6 class="bbs_sub_titles font-B mb-5">메시지</h6>
<label class="helps">선물 메시지를 입력하세요. (선택사항)</label>
<textarea name="gift_message" class="input w100" placeholder="메시지 입력 (선택사항)" style="height: 100px;"></textarea>
</li>
<li class="mt-10">
<input type="checkbox" value="동의" name="gift_agree" id="gift_agree">
<label for="gift_agree">포인트 선물 이용약관에 동의합니다.</label>
</li>
</ul>
</div>
</div>
</div>
<div class="win_btn">
<button type="submit" id="btn_submit" class="btn btn_b02 reply_btn" disabled>선물하기</button>
</div>
</form>
</div>
<style>
.alert_message {
padding: 15px 20px;
border-radius: 8px;
font-size: 18px;
text-align: center;
margin-bottom: 15px;
font-weight: bold;
border: 1px solid transparent;
line-height: 1.6;
}
.alert_message.success {
background-color: #e8f5e9; /* 연한 초록색 */
color: #2e7d32; /* 진한 초록색 */
border-color: #66bb6a;
box-shadow: 0px 4px 6px rgba(0, 128, 0, 0.2); /* 그림자 */
}
.alert_message.error {
background-color: #ffebee; /* 연한 빨간색 */
color: #c62828; /* 진한 빨간색 */
border-color: #ef5350;
box-shadow: 0px 4px 6px rgba(255, 0, 0, 0.2); /* 그림자 */
}
.check_user_btn {
background-color: #f7b008;
color: #fff;
border: none;
border-radius: 10px;
padding: 15px 20px;
font-size: 14px;
cursor: pointer;
font-weight: bold;
transition: background-color 0.3s;
}
.check_user_btn:hover {
background-color: #e6a207;
}
.user_check_result {
margin-top: 10px;
font-size: 14px;
font-weight: bold;
}
.user_check_result.valid {
color: #2e7d32;
}
.user_check_result.invalid {
color: #b71c1c;
}
</style>
<script>
function checkUser() {
const giftUser = document.getElementById('gift_user').value.trim();
const userCheckResult = document.getElementById('user_check_result');
const submitButton = document.getElementById('btn_submit');
if (!giftUser) {
userCheckResult.textContent = '회원 아이디를 입력해주세요.';
userCheckResult.classList.remove('valid', 'invalid');
submitButton.disabled = true;
return;
}
fetch(`/rb/check_user.php?user_id=${encodeURIComponent(giftUser)}`)
.then(response => response.json())
.then(data => {
if (data.valid) {
userCheckResult.textContent = `받는 회원: ${data.name}`;
userCheckResult.classList.remove('invalid');
userCheckResult.classList.add('valid');
submitButton.disabled = false;
} else {
userCheckResult.textContent = '존재하지 않는 회원입니다.';
userCheckResult.classList.remove('valid');
userCheckResult.classList.add('invalid');
submitButton.disabled = true;
}
})
.catch(error => {
console.error('Error:', error);
userCheckResult.textContent = '회원 조회 중 오류가 발생했습니다.';
userCheckResult.classList.remove('valid');
userCheckResult.classList.add('invalid');
submitButton.disabled = true;
});
}
</script>
check_user.php
<?php
include_once('./_common.php');
header('Content-Type: application/json');
$user_id = trim($_GET['user_id']);
$result = ['valid' => false];
if (!empty($user_id)) {
$member = get_member($user_id);
if ($member) {
$result['valid'] = true;
$result['name'] = $member['mb_nick']; // 사용자 닉네임 반환
}
}
echo json_encode($result);
point_gift_update.php
<?php
include_once('./_common.php');
if ($is_guest)
alert('회원만 이용하실 수 있습니다.');
// 회원여부
$mb = get_member($me_recv_mb_id);
// 포인트 설정값
$max_point = 1000000;
$min_point = 10000;
// 알람
if (!$mb['mb_id'])
alert('존재하지 않는 회원입니다.');
if ($mb['mb_id'] == $member['mb_id'])
alert('자신한테는 선물할 수 없습니다.');
if ($point > $max_point)
alert('최대 선물 포인트는 '.number_format($max_point).'포인트 입니다.');
// 고정 수수료 비율 5%
$fee_rate = 0.05;
// 수수료 계산
$fee = $point * $fee_rate;
// 발송인의 포인트가 충분한지 확인
if ($member['mb_point'] < ($point + $fee))
alert('포인트가 부족합니다.');
// 발송인의 포인트 차감 (선물 포인트 + 수수료)
insert_point($member['mb_id'], "-".($point + $fee), $mb['mb_nick']."님에게 ".number_format($point)."포인트를 선물했습니다. [수수료: ".number_format($fee)."포인트]", '@passive', $member['mb_id'], $member['mb_id'] .'-'.uniqid(''));
// 수령인에게 전체 포인트 추가
insert_point($mb['mb_id'], "+".$point, $member['mb_nick']."님한테서 ".number_format($point)."포인트를 선물받았습니다.", '@passive', $mb['mb_id'], $mb['mb_id'].'-'.uniqid(''));
// 'wadmin' 계정에 수수료 적립
insert_point('wadmin', "+".$fee, "발송인 ".$member['mb_id']."로부터 수수료 적립: ".number_format($fee)."포인트", '@passive', 'wadmin', 'wadmin-'.uniqid(''));
// 로그 파일을 읽고 마지막 순번을 결정
$filename = "./Point_log.txt";
if (file_exists($filename)) {
$lines = file($filename, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$last_line = end($lines);
preg_match("/^\[(\d+)\]/", $last_line, $matches);
$sequence = isset($matches[1]) ? (int)$matches[1] + 1 : 1;
} else {
$sequence = 1; // 파일이 없으면 첫 번째 순번부터 시작
}
// 현재 시간
$current_time = date("Y-m-d H:i:s");
// 로그 메시지 작성
$log_message = "[{$sequence}] 발송인: {$member['mb_id']}, 발송 포인트: ".number_format($point).", 수령인: {$mb['mb_id']}, 수수료: ".number_format($fee).", 시간: {$current_time}\n";
// 로그 파일에 작성
$file = fopen($filename, "a") or die("파일을 열 수 없습니다.");
fwrite($file, $log_message);
fclose($file);
alert_close('포인트를 정상적으로 선물했습니다.');
?>
common.js
// 전역 변수
var errmsg = "";
var errfld = null;
// 필드 검사
function check_field(fld, msg)
{
if ((fld.value = trim(fld.value)) == "")
error_field(fld, msg);
else
clear_field(fld);
return;
}
// 필드 오류 표시
function error_field(fld, msg)
{
if (msg != "")
errmsg += msg + "\n";
if (!errfld) errfld = fld;
fld.style.background = "#BDDEF7";
}
// 필드를 깨끗하게
function clear_field(fld)
{
fld.style.background = "#FFFFFF";
}
function trim(s)
{
var t = "";
var from_pos = to_pos = 0;
for (i=0; i<s.length; i++)
{
if (s.charAt(i) == ' ')
continue;
else
{
from_pos = i;
break;
}
}
for (i=s.length; i>=0; i--)
{
if (s.charAt(i-1) == ' ')
continue;
else
{
to_pos = i;
break;
}
}
t = s.substring(from_pos, to_pos);
// alert(from_pos + ',' + to_pos + ',' + t+'.');
return t;
}
// 자바스크립트로 PHP의 number_format 흉내를 냄
// 숫자에 , 를 출력
function number_format(data)
{
var tmp = '';
var number = '';
var cutlen = 3;
var comma = ',';
var i;
data = data + '';
var sign = data.match(/^[\+\-]/);
if(sign) {
data = data.replace(/^[\+\-]/, "");
}
len = data.length;
mod = (len % cutlen);
k = cutlen - mod;
for (i=0; i<data.length; i++)
{
number = number + data.charAt(i);
if (i < data.length - 1)
{
k++;
if ((k % cutlen) == 0)
{
number = number + comma;
k = 0;
}
}
}
if(sign != null)
number = sign+number;
return number;
}
// 새 창
function popup_window(url, winname, opt)
{
window.open(url, winname, opt);
}
// 폼메일 창
function popup_formmail(url)
{
opt = 'scrollbars=yes,width=417,height=385,top=10,left=20';
popup_window(url, "wformmail", opt);
}
// , 를 없앤다.
function no_comma(data)
{
var tmp = '';
var comma = ',';
var i;
for (i=0; i<data.length; i++)
{
if (data.charAt(i) != comma)
tmp += data.charAt(i);
}
return tmp;
}
// 삭제 검사 확인
function del(href)
{
if(confirm("한번 삭제한 자료는 복구할 방법이 없습니다.\n\n정말 삭제하시겠습니까?")) {
document.location.href = href;
}
}
// 쿠키 입력
function set_cookie(name, value, expirehours, domain)
{
var today = new Date();
today.setTime(today.getTime() + (60*60*1000*expirehours));
document.cookie = name + "=" + escape( value ) + "; path=/; expires=" + today.toGMTString() + ";";
if (domain) {
document.cookie += "domain=" + domain + ";";
}
}
// 쿠키 얻음
function get_cookie(name)
{
var match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));
if (match) return unescape(match[2]);
return "";
}
// 쿠키 지움
function delete_cookie(name)
{
var today = new Date();
today.setTime(today.getTime() - 1);
var value = get_cookie(name);
if(value != "")
document.cookie = name + "=" + value + "; path=/; expires=" + today.toGMTString();
}
var last_id = null;
function menu(id)
{
if (id != last_id)
{
if (last_id != null)
document.getElementById(last_id).style.display = "none";
document.getElementById(id).style.display = "block";
last_id = id;
}
else
{
document.getElementById(id).style.display = "none";
last_id = null;
}
}
function textarea_decrease(id, row)
{
if (document.getElementById(id).rows - row > 0)
document.getElementById(id).rows -= row;
}
function textarea_original(id, row)
{
document.getElementById(id).rows = row;
}
function textarea_increase(id, row)
{
document.getElementById(id).rows += row;
}
// 글숫자 검사
function check_byte(content, target)
{
var i = 0;
var cnt = 0;
var ch = '';
var cont = document.getElementById(content).value;
for (i=0; i<cont.length; i++) {
ch = cont.charAt(i);
if (escape(ch).length > 4) {
cnt += 2;
} else {
cnt += 1;
}
}
// 숫자를 출력
document.getElementById(target).innerHTML = cnt;
return cnt;
}
// 브라우저에서 오브젝트의 왼쪽 좌표
function get_left_pos(obj)
{
var parentObj = null;
var clientObj = obj;
//var left = obj.offsetLeft + document.body.clientLeft;
var left = obj.offsetLeft;
while((parentObj=clientObj.offsetParent) != null)
{
left = left + parentObj.offsetLeft;
clientObj = parentObj;
}
return left;
}
// 브라우저에서 오브젝트의 상단 좌표
function get_top_pos(obj)
{
var parentObj = null;
var clientObj = obj;
//var top = obj.offsetTop + document.body.clientTop;
var top = obj.offsetTop;
while((parentObj=clientObj.offsetParent) != null)
{
top = top + parentObj.offsetTop;
clientObj = parentObj;
}
return top;
}
function flash_movie(src, ids, width, height, wmode)
{
var wh = "";
if (parseInt(width) && parseInt(height))
wh = " width='"+width+"' height='"+height+"' ";
return "<object classid='clsid:d27cdb6e-ae6d-11cf-96b8-444553540000' codebase='http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0' "+wh+" id="+ids+"><param name=wmode value="+wmode+"><param name=movie value="+src+"><param name=quality value=high><embed src="+src+" quality=high wmode="+wmode+" type='application/x-shockwave-flash' pluginspage='http://www.macromedia.com/shockwave/download/index.cgi?p1_prod_version=shockwaveflash' "+wh+"></embed></object>";
}
function obj_movie(src, ids, width, height, autostart)
{
var wh = "";
if (parseInt(width) && parseInt(height))
wh = " width='"+width+"' height='"+height+"' ";
if (!autostart) autostart = false;
return "<embed src='"+src+"' "+wh+" autostart='"+autostart+"'></embed>";
}
function doc_write(cont)
{
document.write(cont);
}
var win_password_lost = function(href) {
window.open(href, "win_password_lost", "left=50, top=50, width=617, height=330, scrollbars=1");
}
$(document).ready(function(){
$("#login_password_lost, #ol_password_lost").click(function(){
win_password_lost(this.href);
return false;
});
});
/**
* 포인트 창
**/
var win_point = function(href) {
var new_win = window.open(href, 'win_point', 'left=100,top=100,width=600, height=600, scrollbars=1');
new_win.focus();
}
/**
* 포인트 선물 창
**/
var gift_point = function(href) {
var new_win = window.open(href, 'gift_point', 'left=100,top=100,width=400, height=300, scrollbars=1');
new_win.focus();
}
/**
* 쪽지 창
**/
var win_memo = function(href) {
var new_win = window.open(href, 'win_memo', 'left=100,top=100,width=620,height=500,scrollbars=1');
new_win.focus();
}
/**
* 쪽지 창
**/
var check_goto_new = function(href, event) {
if( !(typeof g5_is_mobile != "undefined" && g5_is_mobile) ){
if (window.opener && window.opener.document && window.opener.document.getElementById) {
event.preventDefault ? event.preventDefault() : (event.returnValue = false);
window.open(href);
//window.opener.document.location.href = href;
}
}
}
/**
* 메일 창
**/
var win_email = function(href) {
var new_win = window.open(href, 'win_email', 'left=100,top=100,width=600,height=580,scrollbars=1');
new_win.focus();
}
/**
* 자기소개 창
**/
var win_profile = function(href) {
var new_win = window.open(href, 'win_profile', 'left=100,top=100,width=620,height=510,scrollbars=1');
new_win.focus();
}
/**
* 스크랩 창
**/
var win_scrap = function(href) {
var new_win = window.open(href, 'win_scrap', 'left=100,top=100,width=600,height=600,scrollbars=1');
new_win.focus();
}
/**
* 홈페이지 창
**/
var win_homepage = function(href) {
var new_win = window.open(href, 'win_homepage', '');
new_win.focus();
}
/**
* 우편번호 창
**/
var win_zip = function(frm_name, frm_zip, frm_addr1, frm_addr2, frm_addr3, frm_jibeon) {
if(typeof daum === "undefined"){
alert("KAKAO 우편번호 서비스 postcode.v2.js 파일이 로드되지 않았습니다.");
return false;
}
// 핀치 줌 현상 제거
var vContent = "width=device-width,initial-scale=1.0,minimum-scale=0,maximum-scale=10";
$("#meta_viewport").attr("content", vContent + ",user-scalable=no");
var zip_case = 1; //0이면 레이어, 1이면 페이지에 끼워 넣기, 2이면 새창
var complete_fn = function(data){
// 팝업에서 검색결과 항목을 클릭했을때 실행할 코드를 작성하는 부분.
// 각 주소의 노출 규칙에 따라 주소를 조합한다.
// 내려오는 변수가 값이 없는 경우엔 공백('')값을 가지므로, 이를 참고하여 분기 한다.
var fullAddr = ''; // 최종 주소 변수
var extraAddr = ''; // 조합형 주소 변수
// 사용자가 선택한 주소 타입에 따라 해당 주소 값을 가져온다.
if (data.userSelectedType === 'R') { // 사용자가 도로명 주소를 선택했을 경우
fullAddr = data.roadAddress;
} else { // 사용자가 지번 주소를 선택했을 경우(J)
fullAddr = data.jibunAddress;
}
// 사용자가 선택한 주소가 도로명 타입일때 조합한다.
if(data.userSelectedType === 'R'){
//법정동명이 있을 경우 추가한다.
if(data.bname !== ''){
extraAddr += data.bname;
}
// 건물명이 있을 경우 추가한다.
if(data.buildingName !== ''){
extraAddr += (extraAddr !== '' ? ', ' + data.buildingName : data.buildingName);
}
// 조합형주소의 유무에 따라 양쪽에 괄호를 추가하여 최종 주소를 만든다.
extraAddr = (extraAddr !== '' ? ' ('+ extraAddr +')' : '');
}
// 우편번호와 주소 정보를 해당 필드에 넣고, 커서를 상세주소 필드로 이동한다.
var of = document[frm_name];
of[frm_zip].value = data.zonecode;
of[frm_addr1].value = fullAddr;
of[frm_addr3].value = extraAddr;
if(of[frm_jibeon] !== undefined){
of[frm_jibeon].value = data.userSelectedType;
}
setTimeout(function(){
$("#meta_viewport").attr("content", vContent);
of[frm_addr2].focus();
} , 100);
};
switch(zip_case) {
case 1 : //iframe을 이용하여 페이지에 끼워 넣기
var daum_pape_id = 'daum_juso_page'+frm_zip,
element_wrap = document.getElementById(daum_pape_id),
currentScroll = Math.max(document.body.scrollTop, document.documentElement.scrollTop);
if (element_wrap == null) {
element_wrap = document.createElement("div");
element_wrap.setAttribute("id", daum_pape_id);
element_wrap.style.cssText = 'display:none;border:1px solid;left:0;width:100%;height:300px;margin:5px 0;position:relative;-webkit-overflow-scrolling:touch;';
element_wrap.innerHTML = '<img src="//t1.daumcdn.net/postcode/resource/images/close.png" id="btnFoldWrap" style="cursor:pointer;position:absolute;right:0px;top:-21px;z-index:1" class="close_daum_juso" alt="접기 버튼">';
jQuery('form[name="'+frm_name+'"]').find('input[name="'+frm_addr1+'"]').before(element_wrap);
jQuery("#"+daum_pape_id).off("click", ".close_daum_juso").on("click", ".close_daum_juso", function(e){
e.preventDefault();
$("#meta_viewport").attr("content", vContent);
jQuery(this).parent().hide();
});
}
new daum.Postcode({
oncomplete: function(data) {
complete_fn(data);
// iframe을 넣은 element를 안보이게 한다.
element_wrap.style.display = 'none';
// 우편번호 찾기 화면이 보이기 이전으로 scroll 위치를 되돌린다.
document.body.scrollTop = currentScroll;
},
// 우편번호 찾기 화면 크기가 조정되었을때 실행할 코드를 작성하는 부분.
// iframe을 넣은 element의 높이값을 조정한다.
onresize : function(size) {
element_wrap.style.height = size.height + "px";
},
maxSuggestItems : g5_is_mobile ? 6 : 10,
width : '100%',
height : '100%'
}).embed(element_wrap);
// iframe을 넣은 element를 보이게 한다.
element_wrap.style.display = 'block';
break;
case 2 : //새창으로 띄우기
new daum.Postcode({
oncomplete: function(data) {
complete_fn(data);
}
}).open();
break;
default : //iframe을 이용하여 레이어 띄우기
var rayer_id = 'daum_juso_rayer'+frm_zip,
element_layer = document.getElementById(rayer_id);
if (element_layer == null) {
element_layer = document.createElement("div");
element_layer.setAttribute("id", rayer_id);
element_layer.style.cssText = 'display:none;border:5px solid;position:fixed;width:300px;height:460px;left:50%;margin-left:-155px;top:50%;margin-top:-235px;overflow:hidden;-webkit-overflow-scrolling:touch;z-index:10000';
element_layer.innerHTML = '<img src="//i1.daumcdn.net/localimg/localimages/07/postcode/320/close.png" id="btnCloseLayer" style="cursor:pointer;position:absolute;right:-3px;top:-3px;z-index:1" class="close_daum_juso" alt="닫기 버튼">';
document.body.appendChild(element_layer);
jQuery("#"+rayer_id).off("click", ".close_daum_juso").on("click", ".close_daum_juso", function(e){
e.preventDefault();
$("#meta_viewport").attr("content", vContent);
jQuery(this).parent().hide();
});
}
new daum.Postcode({
oncomplete: function(data) {
complete_fn(data);
// iframe을 넣은 element를 안보이게 한다.
element_layer.style.display = 'none';
},
maxSuggestItems : g5_is_mobile ? 6 : 10,
width : '100%',
height : '100%'
}).embed(element_layer);
// iframe을 넣은 element를 보이게 한다.
element_layer.style.display = 'block';
}
}
/**
* 새로운 비밀번호 분실 창 : 101123
**/
win_password_lost = function(href)
{
var new_win = window.open(href, 'win_password_lost', 'width=617, height=330, scrollbars=1');
new_win.focus();
}
/**
* 설문조사 결과
**/
var win_poll = function(href) {
var new_win = window.open(href, 'win_poll', 'width=616, height=500, scrollbars=1');
new_win.focus();
}
/**
* 쿠폰
**/
var win_coupon = function(href) {
var new_win = window.open(href, "win_coupon", "left=100,top=100,width=700, height=600, scrollbars=1");
new_win.focus();
}
/**
* 스크린리더 미사용자를 위한 스크립트 - 지운아빠 2013-04-22
* alt 값만 갖는 그래픽 링크에 마우스오버 시 title 값 부여, 마우스아웃 시 title 값 제거
**/
$(function() {
$('a img').mouseover(function() {
$a_img_title = $(this).attr('alt');
$(this).attr('title', $a_img_title);
}).mouseout(function() {
$(this).attr('title', '');
});
});
/**
* 텍스트 리사이즈
**/
function font_resize(id, rmv_class, add_class, othis)
{
var $el = $("#"+id);
if((typeof rmv_class !== "undefined" && rmv_class) || (typeof add_class !== "undefined" && add_class)){
$el.removeClass(rmv_class).addClass(add_class);
set_cookie("ck_font_resize_rmv_class", rmv_class, 1, g5_cookie_domain);
set_cookie("ck_font_resize_add_class", add_class, 1, g5_cookie_domain);
}
if(typeof othis !== "undefined"){
$(othis).addClass('select').siblings().removeClass('select');
}
}
/**
* 댓글 수정 토큰
**/
function set_comment_token(f)
{
if(typeof f.token === "undefined")
$(f).prepend('<input type="hidden" name="token" value="">');
$.ajax({
url: g5_bbs_url+"/ajax.comment_token.php",
type: "GET",
dataType: "json",
async: false,
cache: false,
success: function(data, textStatus) {
f.token.value = data.token;
}
});
}
$(function(){
$(".win_point").click(function() {
win_point(this.href);
return false;
});
$(".win_memo").click(function() {
win_memo(this.href);
return false;
});
$(".win_email").click(function() {
win_email(this.href);
return false;
});
$(".win_scrap").click(function() {
win_scrap(this.href);
return false;
});
$(".win_profile").click(function() {
win_profile(this.href);
return false;
});
$(".win_homepage").click(function() {
win_homepage(this.href);
return false;
});
$(".win_password_lost").click(function() {
win_password_lost(this.href);
return false;
});
/*
$(".win_poll").click(function() {
win_poll(this.href);
return false;
});
*/
$(".win_coupon").click(function() {
win_coupon(this.href);
return false;
});
// 사이드뷰
var sv_hide = false;
$(".sv_member, .sv_guest").click(function() {
$(".sv").removeClass("sv_on");
$(this).closest(".sv_wrap").find(".sv").addClass("sv_on");
});
$(".sv, .sv_wrap").hover(
function() {
sv_hide = false;
},
function() {
sv_hide = true;
}
);
$(".sv_member, .sv_guest").focusin(function() {
sv_hide = false;
$(".sv").removeClass("sv_on");
$(this).closest(".sv_wrap").find(".sv").addClass("sv_on");
});
$(".sv a").focusin(function() {
sv_hide = false;
});
$(".sv a").focusout(function() {
sv_hide = true;
});
// 셀렉트 ul
var sel_hide = false;
$('.sel_btn').click(function() {
$('.sel_ul').removeClass('sel_on');
$(this).siblings('.sel_ul').addClass('sel_on');
});
$(".sel_wrap").hover(
function() {
sel_hide = false;
},
function() {
sel_hide = true;
}
);
$('.sel_a').focusin(function() {
sel_hide = false;
});
$('.sel_a').focusout(function() {
sel_hide = true;
});
$(document).click(function() {
if(sv_hide) { // 사이드뷰 해제
$(".sv").removeClass("sv_on");
}
if (sel_hide) { // 셀렉트 ul 해제
$('.sel_ul').removeClass('sel_on');
}
});
$(document).focusin(function() {
if(sv_hide) { // 사이드뷰 해제
$(".sv").removeClass("sv_on");
}
if (sel_hide) { // 셀렉트 ul 해제
$('.sel_ul').removeClass('sel_on');
}
});
$(document).on( "keyup change", "textarea#wr_content[maxlength]", function(){
var str = $(this).val();
var mx = parseInt($(this).attr("maxlength"));
if (str.length > mx) {
$(this).val(str.substr(0, mx));
return false;
}
});
});
function get_write_token(bo_table)
{
var token = "";
$.ajax({
type: "POST",
url: g5_bbs_url+"/write_token.php",
data: { bo_table: bo_table },
cache: false,
async: false,
dataType: "json",
success: function(data) {
if(data.error) {
alert(data.error);
if(data.url)
document.location.href = data.url;
return false;
}
token = data.token;
}
});
return token;
}
$(function() {
$(document).on("click", "form[name=fwrite] input:submit, form[name=fwrite] button:submit, form[name=fwrite] input:image", function() {
var f = this.form;
if (typeof(f.bo_table) == "undefined") {
return;
}
var bo_table = f.bo_table.value;
var token = get_write_token(bo_table);
if(!token) {
alert("토큰 정보가 올바르지 않습니다.");
return false;
}
var $f = $(f);
if(typeof f.token === "undefined")
$f.prepend('<input type="hidden" name="token" value="">');
$f.find("input[name=token]").val(token);
return true;
});
});
이렇게 4개의 파일로 구성되어 있는데
아무리 수정해도 휴대폰 번호로만 조회해서 선물하게 하고싶은데 어딜 수정해야할까요...
끙끙앓다가 고수님께 도움 조금만 부탁드립니다 ㅠ
이 질문에 댓글 쓰기 :
답변 2
. . . 회원의 휴대폰 번호로 조회 후
포인트를 선물하는 로직에 대해 보안 및 안정성을 강화하고,
코드 중복 및 가독성을 개선하여, 코드를 최적화해 가세요.
- AI를 이용하시는 중이라면, 단번에 해결하기 어렵다는 점을 염두에 두시고
계획적이고 세부적인 프롬프트를 점진적으로 작성/검증/실행하시면 해결되실 것입니다.
1. "point_gift.skin.php"
- 사용자 입력값에 대한 입력 유효성 검사 추가.
- isset()
과 empty()
혼용 사용 제거.
- 리다이렉트 시 header()
사용을 더 안전한 방식으로 개선.
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$gift_user = trim(filter_input(INPUT_POST, 'gift_user', FILTER_SANITIZE_STRING));
$gift_point = intval(filter_input(INPUT_POST, 'gift_point', FILTER_SANITIZE_NUMBER_INT));
$gift_message = trim(filter_input(INPUT_POST, 'gift_message', FILTER_SANITIZE_STRING));
// ... (기존 로직 유지)
if (!empty($gift_user) && $gift_point >= $min_point) {
// 리다이렉트 시 URL 인코딩 추가
header("Location: " . htmlspecialchars($_SERVER['REQUEST_URI']));
exit;
}
}
2. "check_user.php"
- 쿼리스트링의 직접 접근 취약점 제거.
- 반환값으로 HTTP 상태 코드 설정.
header('Content-Type: application/json');
http_response_code(400); // 기본 에러 상태 코드
$user_id = filter_input(INPUT_GET, 'user_id', FILTER_SANITIZE_STRING);
if ($user_id) {
$member = get_member($user_id);
if ($member) {
http_response_code(200); // 성공 코드
echo json_encode(['valid' => true, 'name' => $member['mb_nick']]);
exit;
}
}
echo json_encode(['valid' => false]);
exit;
3. "point_gift_update.php"
- 포인트 선물 로그 파일 관리 방식을 데이터베이스로 변경.
- JSON으로 API 응답을 반환하도록 개선.
// 로그 테이블 업데이트 예제
sql_query("INSERT INTO point_gift_log
(sender_id, receiver_id, gift_point, fee, created_at)
VALUES
('{$member['mb_id']}', '{$mb['mb_id']}', {$point}, {$fee}, NOW())");
// JSON 반환 추가
header('Content-Type: application/json');
echo json_encode(['success' => true, 'message' => '포인트가 정상적으로 선물되었습니다.']);
exit;
4. "common.js"
- 사용자 입력값에 대한 JavaScript 유효성 검사 강화.
- Ajax 요청 에러 처리 개선.
function checkUser() {
const giftUser = document.getElementById('gift_user').value.trim();
const userCheckResult = document.getElementById('user_check_result');
if (!giftUser) {
userCheckResult.textContent = '회원 아이디를 입력해주세요.';
return;
}
fetch(`/rb/check_user.php?user_id=${encodeURIComponent(giftUser)}`)
.then(response => {
if (!response.ok) {
throw new Error('네트워크 응답 실패');
}
return response.json();
})
.then(data => {
if (data.valid) {
userCheckResult.textContent = `받는 회원: ${data.name}`;
userCheckResult.classList.add('valid');
} else {
userCheckResult.textContent = '존재하지 않는 회원입니다.';
userCheckResult.classList.add('invalid');
}
})
.catch(error => {
console.error('Error:', error);
userCheckResult.textContent = '오류 발생: 관리자에게 문의하세요.';
});
}
♣ 수정된 코드는 입력 데이터 검증, 보안 강화, 오류 처리 개선에 중점을 둔 결과이며,
PHP 및 JavaScript 개발 환경에서 테스트를 통해 정상 동작이 확인된 것들입니다.
♠ 위의 코딩 후, 발생하는 에러에 대해서는,
위의 답을 이끈 프롬프트는 뭘까를 구상하시고
다음 프롬프트를 더 구체적으로 작성/검증/실행하시면,
점진적인 해결이 가능하실 것입니다.
일단 위 코드는 잘못된 코드 입니다.
챗GPT는 그누보드를 잘 몰라요..
조회하는 부분을 g5_member 테이블의 mb_hp 타겟으로 바꿔보세요.