들어가기 전에

이 글은 리뉴얼 프로젝트를 진행함에 있어 AS-IS 분석을 정리하면서 분석 리딩 회의때 물어볼 것들 정리하고, TO-BE 정책을 마련하기 위해 작성되었습니다.

명품지식 조회

1. 개요

목록조회

  • legacy file: info_list.php
  • include file: inc_login_break
  1. 오늘의 지식인 아이디
  2. 가장 많이 본 지식 TOP5
  3. 명품지식
  4. 답변있는 지식
  5. 답변없는 지식

상세조회

  1. 지식 조회
  2. 지식 답변 조회
  3. 지식 답변 의견 조회
  4. 인기 지식 정보 갱신(동일아이디 제외)
  5. 지식 조회 수 갱신

분류

  1. 질문
  2. 정보
  3. 뉴스
  4. 필톡

2. 주요 프로세스 및 기능

베스트 지식

  • legacy file: info_last_best.php

view count로 선정함.

오늘의 지식인

  • legacy file: todays_info_masters.php

선정 주체 확인 필요.
batch인가 admin인가.

명품지식 목록 조회

  • 첫번째 페이지와 그 외 페이지에 사용하는 쿼리가 다름.
    • 첫번째 페이지:
      SELECT *
      FROM info_board
      ORDER BY ask_no DESC
      LIMIT $start, $rows
    • 그외 페이지:
      SELECT *
      FROM info_board
      WHERE ask_no IN (
      ".$ask_no_text"
      )
      ORDER BY ".$order_by_text"
  • 미답변 목록 조회 개수 제한
    • 조회 전체 개수에 따라 조회 ROW 개수 변경 (MAX 120)
      • 100: 10
      • 500: 30
      • 2000: 40
      • 5000: 60
      • 최대: 120

명품지식 상세 조회

  • 조회 수 갱신
    • 비로그인 조회는 제외
  • 베스트 지식 조회 수 갱신
    • 비로그인 조회는 제외
    • 중복아이디 제외

프로세스

  1. path param 형식으로 지식 ID 전달: ifv_{브랜드명}_{지식ID}
  2. 로그인 체크
  3. 지식조회
    SELECT *
    FROM info_board
    WHERE ask_no = '$ask_no'
  4. 인기 지식 정보 갱신
    SELECT *
    FROM info_last_best
    WHERE ask_no = '$ask_no'
    UPDATE info_last_best
    SET no_view = no_view + $view_plus,
    last_view_id = $last_view_id
    WHERE ask_no = $ask_no
  5. 지식 조회수 갱신
    UPDATE info_board
    SET view = view+1
    WHERE ask_no = $ask_no
  6. 지식 답변 조회
    SELECT *
    FROM info_answer
    WHERE ask_no = $ask_no AND
    admin_id_check != '1'
    ORDER BY admin_id_check DESC, answer_no
  7. 지식 답변 의견 조회
    SELECT *
    FROM info_answer_memo
    WHERE ask_no = $ask_no AND
    answer_no = $row_answer[answer_no]
    ORDER BY memo_no

명품지식 등록

write_form 폼 작성 후 info_save.php로 전송

1. 개요

  • 명품지식을 분류별로 등록
  • 등록된 명품지식에 답변을 등록
  • 명품지식답변에 의견을 등록

2. 주요 프로세스 및 기능

주요 테이블

테이블 설명
echo_page_table 검색 Default html 페이지
taboo_table 금지어
info_board 명품지식
info_answer 지식답변
info_answer_memo 지식답변의견
category_table 카테고리
sub_category_table 서브카테고리
brand 브랜드
no_info_check_user 지식 등록 제한자
info_depart 분류(사용하지 않는 것으로 보임)
info_last_best 베스트 지식
user_goods_stats 사용자 기타 정보 상태
feelway_etc2.info_keyword_indexing 지식글 제목 인덱스
info_word_indexing 지식글 분류 인덱스(브랜드, 카테고리, 서브카테고리, 그 외 검색어)

1.본인인증

buy_only 체크
buy_only값이 1인 경우 본인인증페이지로 리다이렉션.

본인인증이 된 회원만 등록 가능

  • 간편회원은 등록 불가
  • SNS 회원은 등록 가능

사용자 조회:

SELECT *
FROM user
WHERE u_id=$feel_id
  1. selectbox 생성용 코드 조회
  • 카테고리 조회
    SELECT *
    FROM category_table
    ORDER BY cate_no
  • 서브카테고리 조회
    SELECT *
    FROM sub_category_table
    WHERE cate_no = $row_c[cate_no]
    ORDER BY desc_index
  • 브랜드 조회
    SELECT *
    FROM brand
    ORDER BY brnad_name
  1. 세션 리로드
    작성 완료시 만료를 방지하기 위해 세션 시간 초기화

  2. 이미지 업로드 (명품지식/답변만 해당)


  • 가능 확장자: jpg, jpeg, gif
  • 크기: 5M 이하
  • 업로드 개수 제한: 파일명(full url) + 구분자("||") 문자열 길이가 400 byte
  • 디렉토리: upfile_info_##/YYYYMM
  • 이미지도메인: http://img###*.feelway.com

이미지 태그 리턴

  1. 저장 (file: info_save.php)
    넘겨 받은 파라미터로 데이터 처리

    5-1. 로그인 체크
    5-2. 금지어 체크

     SELECT *
     FROM taboo_table

    금지어를 조회해서 제목과 내용에 금지어가 포함되어 있으면 등록 불가

    5-3. 금지 판매자 확인

     SELECT *
     FROM no_info_check_uwer
     WHERE u_id=$u_id AND
     application = '1'

    지식 등록 제한자 조회 후 제한된 작성자면 등록 불가

    5-4. 명품지식 번호 생성

     SELECT max(ask_no)
     FROM info_board
     WHERE code = $code

    가장 최근 게시글 가져와서 ask_no + 1 처리.
    (AUTU_INCREMENT 수동 처리)

    5-5 코드명칭 조회

    • 카테고리명

      SELECT *
      FROM category_table
      WHERE cate_no = $cate_no
    • 서브카테고리명

      SELECT *
      FROM sub_category_table
      WHERE cate_no = $cate_no AND
      sub_cate_no = $sub_cate_no
    • 브랜드명

      SELECT *
      FROM brand
      WHERE brnad_no = $brand_no

      5-6 지식 등록

      INSERT INTO info_board(
      code, ask_no, ask_answer, ... file
      )
      

      5-7 검색어 키워드 저장(제목)

      INSERT INTO feelway_etc2.info_keyword_indexing(
        ask_no,
        keyword
      )
      VALUES(
        $word_array[$i]
      )

      5-8 베스트 지식 default 저장

      INSERT INTO info_last_best(
        ask_no,
        no_view,
        daytime,
        ask_info
      ) VALUES (
        0,
        $daytime,
        $ask_info
      )

      5-9 사용자 기타정보 갱신

    • 질문인 경우 등록 개수 갱신

      UPDATE user_goods_stats 
      SET info_ask_count = info_ask_count + 1
      WHERE u_id = $feel_id
    • 정보인 경우 등록 개수 갱신

      UPDATE user_goods_stats
      SET info_info_count = info_info_count + 1
      WHERE u_id = $feel_id
    • 뉴스인 경우 등록 개수 갱신

      UPDATE user_goods_stats
      SET info_news_count = info_news_count + 1
      WHERE u_id = $feel_id

      5-10 검색 HTML 페이지 생성

    • 등록된 전체 지식 건수 조회

      SELECT count(*) 
      FROM info_board
      WHERE code = 'info'
    • 지식 글 조회

       SELECT *
      FROM info_board
      WHERE code = 'info' AND
      admin_view_check = '0' AND
      reply_n > 0 
      ORDER BY ask_no DESC
      limit $orws
    • 조회한 지식 글 수의 답변 조회

      SELECT *
      FROM info_board
      WHERE code = 'info' AND
      reply_n = 0
      ORDER BY ask_no DESC limit $orw2

    5-11 HTML 생성

    • 답변 조회

      UPDATE echo_page_table
      SET page_text = $page_text
      WHERE page_no=$page_no -- 106
    • 답변

      SELECT *
      FROM info_answer
      WHERE ask_no=$row[ask_no] AND
      admin_id_check != '1'

이미지 리사이즈 및 워터마크

  • imagemagick 사용

XSS방지

  • <img></img>만 허용

검색어 추출

  • 명품지식 등록
    • 명품지식 제목에 사용된 단어 추출
       - table: feelway_etc2.info_keyword_indexing
  • 명품지식 답변 등록시
    • 지식 및 답변 제목/내용에서 검색어 추출
      • info_word_indexing
      • 브랜드: bno ###
      • 카테고리: cno ###
      • 서브카테고리: scno ###
      • 그 외 지식글 및 답글에서 검색어 추출

삭제된 기능

  • 파일 업로드

명품지식 수정

1. 개요

  1. 명품지식글 수정/삭제
  2. 명품지식답변 수정/삭제
  3. 명품지식답변의견 수정/삭제

2. 주요 프로세스 및 기능

  • 지식글 수정/삭제
    • 작성자 본인만 가능
    • 답글이 없는 경우만 가능
    • 수정 시 금지어 적용
  • 답변 수정/삭제
    • 작성자 본인만 가능
    • 답변의견이 없는 경우만 가능
    • 수정 시 금지어 적용
  • 답변의견 수정/삭제
    • 작성자 본인만 가능
    • 수정 시 금지어 적용
  • 나의 관심지식 추가
  • 명품지식 추천/부적절 신고
  • 명품지식 답변추천/답변부적절 신고
  • SNS 공유

관심지식

1. 개요

2. 주요 프로세스 및 기능

  • 관심지식 추가
  • 나의 관심지식 관리
    • 스크랩 등록/해제
      • 나의 홈에 명품지식 스크랩 등록된 지식 표시
      • 관심지식 설명 추가
      • 관심지식 삭제
  • 내가 등록/질문한 지식
  • 내가 답변한 지식
  • 내 글에 최근 답변 된 지식
    • 최근 20일 이내 작성된 답변만 표시
    • 동일지식글에 달린 답변은 최대 5개만 표시
  • 내 답변에 최근 등록된 의견
    • 최근 20일 이내 작성된 답변만 표시
    • 노출금지건 제외 (지식, 답변)

가장 많이 본 지식 TOP 5

기간(시간)별 조회수가 많은 게시물을 셀렉트한다.

하루 동안, 일주일 동안, 한달 동안의 기간 별 조회수가 많은 명품 지식 BEST TOP 5.
주로 글작성과 게시물 뷰 페이지에 관련 함수가 호출된다.
명품지식 관련 컨트롤러에서 write()(글작성), view()(뷰)로 나눠 흐름을 따라가면서 플로우를 살펴봤다.

  • 테이블 : info_last_best

  • 테이블 명세서

이름 데이터유형 NULL 허용 기본값 코멘트
ask_no INT NOT NULL '0' 게시글 번호
no_view INT NULL '0' 조회수
last_view_id VARCHAR NULL NULL 게시글을 본 사람들
daytime INT NULL NULL 마지막으로 본 날짜
ask_info ENUM NULL NULL 명품지식 게시글 타입
  • 쿼리
    현재시간으로 부터 하루, 일주일, 한달을 기간으로하여 유저들이
    해당 게시글을 마지막으로 본 날짜를 체크하는 daytime을 기준으로해서
    info_last_best 테이블과 info_board테이블을 조인해 데이터를 가져와야한다.
    순서는 조회수 기준이고 5개만.

[AS - IS]

SELECT ask_no
FROM info_last_best
WHERE daytime >= ? AND
daytime <= ?
ORDER BY no_view DESC
LIMIT 5

[TO - BE]

SELECT ib.* 
FROM info_board 
LEFT JOIN info_board 
WHERE daytime ? AND ? 
ORDER BY no_view DESC
LIMIT 5

TO-BE에서 info_boardinfo_last_best를 조인하는 이유는 infoBoardHelper에서 getBestInfo함수를 호출하여 info_board, info_last_best테이블의 데이터를 가공하여 $list 변수에 가공한 데이터들을 push하고 있기 때문이다.

image.png


  • 프로세스
  1. 게시글 작성 -> last daytime, last view user, no_view, ... 정보 인서트
  2. 게시글 보기 -> last daytime, last view user, no_view, ... 정보 업데이트

게시글 작성(saveAsk)

정확히 게시글 작성 후 저장 하면서 게시글 번호($ask_no)와 게시글 타입($ask_info)을 받아서 info_last_best 테이블의 ask_no, no_view, daytime, ask_info를 insert한다.
호출 함수명: input_info_lb($ask_no, $ask_info);

뷰(view)

게시글의 내용이 보여짐.
게시글을 클릭하면 게시글 번호($ask_no)와 유저 아이디($feel_id)를 받아서
info_last_bestno_view 조회수를 증가시켜준다.
호출 함수명: view_count_info($ask_no, $feel_id);

오늘의 지식인

관리자 또는 배치로 운영되는 내용으로 알고있지만 분석팀한테 정확한 확인 요구 필요함

[AS-IS]

<?
$sql_a = "select * from todays_info_masters where app_check='1' order by main_no desc limit 1";

$result_a = mysqli_query($feel_mysql_connect, $sql_a);
$row_a = mysqli_fetch_array($result_a);
$todays_masters_list = explode("||", $row_a[todays_masters], 70);
echo "";
for ($i = 1; $i < 70; $i++) {
    if ($todays_masters_list[$i] == "") break;
    $todays_masters_text .= "<a href='http://www.feelway.com?" . $todays_masters_list[$i] . "'>";
    $todays_masters_text .= not_googling($todays_masters_list[$i]);
    $todays_masters_text .= "</a> ";
    if ($i % 3 == 0) $todays_masters_text .= " ";
}
?>

todays_masters컬럼에 ||구분자로 유저를 나누고 최고 70명까지 할당 되어 있다.
홈링크를 연결해주기 위해 루프를 돌리는데 70번째가 넘거나 todays_masters가 공백일 경우 루프를 나간다.

[TO-BE]

@foreach(explode("||", $todayInfoMasters->todays_masters, 70) as $item)
 @if(!empty($item))
    <a href="http://www.feelway.com?{{$item}}">{!! App\Helpers\Common::robots($item) !!}</a>
 @endif
@endforeach

쓰기

1)글 작성과 2)답변 작성을 한번에 처리.

$mode = $_POST['mode'];

1) 글작성
mode = ask

[AS-IS]

function input_ask(){
    // 파라미터 받기
    $code = $_POST['code'];
    ...

    // 게시글 인서트
    $sql = "insert ...";
    ...

    // 불량 이용자 체크
    $check_id_info_write = check_id($u_id);
    ...    

    // 오늘의 베스트 클릭 지식 부분
    input_info_lb($ask_no, $ask_info);

    return $ask_no
}

2) 답변 작성
mode = answer

[AS-IS]

function input_answer(){
    // 파라미터 받기
    $code = $_POST['code'];
    $ask_no = $_POST['ask_no'];
    ...

    // `$ask_no`에 대한 info_board 데이터 조회: `re_content_all`컬럼에 데이터를 넣기 위한 것으로 보임.
    $query_ask = "select * from info_board where ask_no=$ask_no";
    $result_ask = mysqli_query($feel_mysql_connect, $query_ask);
    $row_ask = mysqli_fetch_array($result_ask);

    // 가장 최근 답변 조회한 후 `answer_no` 자동증가값 가산처리
    $query = " select max(answer_no) from info_answer";
    if ($row = mysqli_fetch_array($result)) {
        $answer_no = $row["max(answer_no)"] + 1;
    } else {
        $answer_no = 1;
    }

    // 제목, 내용 데이터 가공
    $title = htmlspecialchars($title);
    $title = strip_tags($title);
    $content = strip_tags($content, "<img>");
    $content = str_replace("(", "(", $content);
    $content = addslashes(stripslashes(removeEvilAttributes($content)));

    // 회원, 답변 노출, 비노출 관리자 플래그 체크
    if(strlen($feel_id) > 1){
        $check_id_info_write = check_id($feel_id);
        if($check_id_info_write == '1')
            $admin_id_check = '1'; // 아이디가 지식쓰기 금지가 되어 있으면, 비답으로 등록 
        else
            $admin_id_check = '2'; // 정상적인 아이디면 정식으로 등록
     }else {
        $admin_id_check = '1'; // 비회원 답변은 비답으로 등록
     }

    // `info_answer`테이블에 답변 데이터 인서트
    $sql = "insert into info_answer ...";

      // `$re_content_all`에 또 제목과 내용을 합친 데이터를 넣음
    $re_content_all = $title . $content;
    $re_content_all = strip_tags($re_content_all);
    $re_content_all = nsplit($re_content_all, 200);
    $re_content_all = $row_ask[re_content_all] . " " . $re_content_all; //$row_ask는 info_board에서 옴 append 시키는 것.
    $re_content_all = strip_tags($re_content_all);
    $re_content_all = addslashes($re_content_all);

    // 같은 내용을 `info_board`테이블에도 또 답변 데이터 업데이트
    $sql_reply = "update info_board set last_answer_date='$date_write', re_content_all='$re_content_all' where ask_no='$ask_no' limit 1";
    @mysqli_query($feel_mysql_connect, $sql_reply);

    // 해당 글 답변 개수 조회후 `info_board`업데이트
    $sql_reply_n = "select count(*) from info_answer where ask_no='$ask_no' and admin_id_check!='1'";
    $result_reply_n = mysqli_query($feel_mysql_connect, $sql_reply_n);
    $row_reply_n = mysqli_fetch_array($result_reply_n);
    $reply_n_count = $row_reply_n["count(*)"];
    $sql_reply_n = "update info_board set reply_n=$reply_n_count where ask_no='$ask_no' limit 1";

    // 관리자 플래그 체크
    if ($admin_id_check == "1") {
        if ($check_id_info_write == '1') {
//                echo "<script> alert('비회원 답변은 필웨이 검토후 등록됩니다.') < /script>";
        } else
            echo "<script> alert('비회원 답변은 필웨이 검토후 등록됩니다.') </script>";
    }
    if ($admin_id_check == "2") {
        $sql_stats = "update user_goods_stats set info_answer_count=info_answer_count+1 where u_id='$feel_id'";
        @mysqli_query($feel_mysql_connect, $sql_stats);
    }

    // 형태소 체크
    $sql_word_delete = "delete from info_word_indexing where no='$ask_no'";
    ...

    return $ask_no;
}
  • 금지어 체크 함수:
    include_once $_SERVER['DOCUMENT_ROOT'] . '/taboo_function.php';

  • 오늘의 베스트 클릭 지식 관련 함수:
    include_once $_SERVER['DOCUMENT_ROOT'] . '/info_lb_function.php';

[TO-BE]

call_cate_name(), call_sub_cate_name(), call_depart_name()의 단순 조회 쿼리 관련 함수들은 향후 redis로 캐싱해서 데이터를 불러오는 것으로 변경할 것이다.

중복되는 함수와 필요없는 함수들 제거할 것.

정지된 판매자 회원 체크

application 값이 1인 유저의 정보를 모두 조회.

  • 테이블 : no_info_check_user

  • 테이블 명세서

이름 데이터유형 NULL 허용 기본값 코멘트
main_no INT NOT NULL AUTO_INCREMENT PK
u_id INT NOT NULL '' 유저 아이디
check_reason TEXT NULL 기본값 없음 금지어 내용
check_date DATETIME NULL NULL 정지회원 등록 날짜
lift_date DATETIME NULL NULL ?
application ENUM NULL NULL 노출:0, 비노출:1
  • 정책 :
    application 값이 1이면 게시글 비노출

[AS-IS]

function check_id($u_id){
    $result = "
        SELECT *
        FROM no_info_check_user
        WHERE u_id = ? AND
        application = 1
    ";
    // 데이터바인딩 처리
    if($result['application'])
        return 1;
    else
        return 0;
}

// ...

$check_id_info_write = check_id($u_id);
if (check_id_info_write == '1') return 0;

// 답변 부분 인서트 할 때 한번 더 체크
if(strlen($feel_id) > 1){ // 로그인 시
    $check_id_info_write = check_id($feel_id);
    if($check_id_info_write == '1')
        $admin_id_check = '1'; // 비노출로 업데이트
    else
        $admin_id_check = '2'; // 노출로 업데이트
}else{
    $admin_id_check = '1'; // 로그인 안한 회원이면 비노출로 업데이트
}

  • file
    • info_view.php
  • function
    • view_count_info($ask_no, $feel_id)
      -> info_last_best 테이블 업데이트: 조회수 증가

추천

code, ask_no 인자로 받고 recom_ask() 호출

function recom_ask(code, ask_no){
    // info_recom_count.php에서 처리
}

해당 게시글 번호로 조회

SELECT *
FROM info_board
WHERE code = $code AND
ask_no = $ask_no

아이디 필터링해서 체크하여
정보가 없으면 해당 게시글 추천수를 갱신
정보가 있으면 이미 추천버튼을 누른 유저로 판단.

UPDATE info_board
SET recom_count = recom_count + 1, recome_id = $recom_id
WHERE code = $code AND
ask_no = $ask_no

유저 정보에서 추천 카운트 갱신

UPDATE user_goods_stats
SET info_recom_count = info_recom_count + 1
WHERE u_id = $row[u_id]

신고

$go의 값이 unrecom_##일 경우.

해당 게시글 조회

SELECT *
FROM info_board
WHERE code = $code AND
ask_no = $ask_no

신고를 안한 아이디면 해당 게시글의 비추천 수 카운트 갱신

UPDATE info_board 
SET unrecom_count = unrecom_count + 1, recom_id = $recom_id
WHERE code = $code AND
ask_no = $ask_no

질문 게시글 삭제

code, ask_no, n을 인자 값으로 delete_ask() 호출.

delete_ask(code, ask_no, n){
    // n이 0보다 클 경우 답변이 있는 상황
    // info_modify.php로 이동하여 처리
}

$mode값이 delete일 경우

해당 게시글 조회

SELECT *
FROM info_board
WHERE code=$code AND
ask_no=$ask_no

파일 있으면 삭제

$file = $row_del[file];
$remove_file = explode("||", $file);
for($i=0;;){
    if(strlen($remove_file[$i] > 30)){
        exec("rm -f ./$remove_file[$i]");
        echo "<br>";
    }else{
        exec("rm -f ./upfile_info/$remove_file[$i]");
        echo "<br>";
        if($remove_file[++$i] == "") break;
    }
}

파일까지 삭제 했으면 게시글 삭제

DELETE FROM info_board
WHERE code=$code AND
ask_no=$ask_no;

관심지식도 삭제

DELETE FROM interest_info 
WHERE ask_no=$ask_no

관심지식

  • 테이블 명세서
이름 데이터유형 NULL 허용 기본값 코멘트
main_no INT NOT NULL AUTO_INCREMENT PK
u_id INT NOT NULL '' 유저 아이디
div_interest ENUM('0','1','2','3') NULL '0' 스크랩허용
ask_info ENUM('ask','info','news','talk') NULL NULL 게시글 타입
ask_no INT NOT NULL '0' 게시글 번호
title VARCHAR NULL NULL 제목
content VARCHAR NULL NULL 내용
intro VARCHAR NULL NULL ?
brand_no INT NULL NULL 브랜드 번호
brand_name VARCHAR NULL NULL 브랜드명
cate_no INT NULL NULL 카테고리 번호
cate_name VARCHAR NULL NULL 카테고리명

관심지식 등록

  • 라우터
    apps/info/interest/{askNo}

  • 컨트롤러
    InterestInfo::add

  • 사용 모델

    • InterestInfo
    • InfoBoard
  • 파라미터
    ask_no

  1. 관심지식 등록 여부 확인
  2. 명품지식 조회
  3. 나의 관심지식으로 등록

내가 등록한 지식/답변

내가 등록한 지식

  1. 페이징을 위한 전체 조회 카운트
  2. 내가 등록한 지식 조회

나의 답변이 있는 지식 (내가 답변한 지식)

  1. 페이징을 위한 전체 조회 카운트
  2. 나의 답변이 있는 지식/답변 조회

info_board, info_answer 테이블 조인해서 조회