질문/조언질답게시판
Extra Form
PHP PHP 8.1
CMS Rhymix 2.x

https://xetown.com/questions/1591602

 

위 질문에 이은 질문입니다!

 

getMyVote 함수에서 지속적으로 null 값을 반환해서, 혹시나 해서 세션이 존재하면 DB쿼리를 하지않고 바로 세션을 반환하는 코드를 주석처리했더니 정상 작동합니다.

 

[댓글의 경우]

    function getMyVote()
    {
        if(!$this->comment_srl) return false;
/*         if(isset($_SESSION['voted_comment'][$this->comment_srl]))
        {
            return $_SESSION['voted_comment'][$this->comment_srl];
        } */

 

[document의 경우]

    function getMyVote()
    {
        if(!$this->isExists())
        {
            return false;
        }

/*         if(isset($_SESSION['voted_document'][$this->document_srl]))
        {
            return $_SESSION['voted_document'][$this->document_srl];
        } */

 

 

혹시 jquery를 통해 버튼 클릭시에는 세션이 정상적으로 저장이 되지 않는걸까요?

추천 버튼을 클릭하는 부분은 제가 별도의 모듈이나 애드온을 만들어서 세션을 잃어버리게 하지 않았고

단순히 스킨단에서 자바스크립트로 아래와 같이 구현했습니다

 

        if(str.includes("추천문구"))    {
            $("#recomment-write").prev("li").find("추천 버튼 클래스").click();
        } else if(str.includes("비추천문구")){
            $("#recomment-write").prev("li").find("비추천 버튼 클래스).click();
        }

  • profile

    이와 관련된 댓글을 달까 했는데 질문을 올리셨네요.

    db 쿼리 했을때 추천한 내역이 확인이 되지 않을 이유가 없어서 위쪽 세션에서 의도된 값이 저장이 안되거나 혹은 세션유무를 체크하는 부분이 잘못되었을 것으로 생각이 되었습니다. (의도 되지 않은 세션값이 반환되는 상황 : 주석을 하니 아래 코드로 진행하는 것으로 보아..)

    디버그를 화면 패널에서 확인하는 것 + 파일에 기록을 이용하셔서

    $_SESSION['voted_document'][$this->document_srl]

    값이 어떻게 담기는지 확인해 볼 필요도 있겠습니다.

    debugPrint($_SESSION['voted_document'][$this->document_srl]);

    화면에서 보지 못해도 디버그 파일에는 기록이 되니 스크립트로 추천될 때 어떤 값이 기록되는지 확인해 보고 원인을 찾아갈 수 있지 않을까 하는 생각을 해봤습니다.

  • profile profile

    캡처.PNG

     

    jquery를 통해 추천했을때는 false로 표시되는것 같습니다. 이 부분 확인을 덕분에 할수 있었습니다 감사합니다.

     

    그런데

     

            if(isset($_SESSION['voted_document'][$this->document_srl]))
            {
                return $_SESSION['voted_document'][$this->document_srl];
            }

     

    이 부분을 주석 처리하면

     

    jquery를 통해 추천을 하더라도

     

    캡처2.PNG

    추천했다는 1 값을 잘 반환하네요....

    아마 DB에서 return $_SESSION['voted_document'][$this->document_srl] = $output->data->point; 을 통해 반환했던 값이 세션에 저장되어서 1을 잘 표시하는것 같은데

     

    문제는 결국 jquery 통해 클릭시 세션이 잘 안들어간다는거군요 ;_;

     

    이 이상으로는 제 한계인것 같습니다 ㅠㅠ

     

     

  • profile profile
    네. 스크립트로 추천이 진행될때 왜 세션에 추천,비추천에 해당하는 값이 저장이 안되고 false로 지정이 되는지 관련 코드가 포함된 함수의 버그? 또는 방식을 확인해봐야 할 것 같습니다.
  • profile

    DB에 member_srl이 저장된다면 로그인 상태를 인식한다는 뜻이니 세션 작동에는 이상이 없는 것으로 보입니다.

     

    $_SESSION['voted_document'][$document_srl]이 false로 저장되는 경우는 자신의 글을 추천하려고 하거나, 글 작성자와 동일한 IP에서 추천을 시도한 경우가 대부분으로, "추천한 적 없음"이라는 뜻입니다. 그 밖에 여기에서 false로 저장하는 코드가 좀 의심스러워 보이기는 하는데, 정상적으로 추천이 이루어져 DB에 저장되었다면 해당 부분이 실행되지는 않습니다.

  • profile profile

    추측입니다만 먼저 질문에서 캡처로 올려주신 log 에 ip가 0.0.0.0 으로 기록되어 보이던데 추천을 시도한 아이피가 0.0.0.0 이라서 발생하는 문제가 아닐지...

  • profile profile

    다만, 그런 경우라면 애초에 추천이 되지 않았겠지요.

    추천이 되었든 안 되었든 스킨에서 에러를 무시하고 무조건 추천된 것처럼 추천수를 높여서 표시해 주고 있을 가능성도 없지는 않습니다. 어제 잠깐 스킨소스가 올라왔었는데 해당 기능에 exec_json을 사용하지 않고 싸제(?)로 구현해 놓은 것 같았거든요. 그러나 직접 클릭하면 추천이 된다고 하신 것으로 보아, IP가 문제는 아닌 것으로 보입니다.

  • profile profile
    저희쪽에서 라이믹스의 constants.php를 수정해서 ip를 모두 동일하게 운영중이기는 합니다!
    해당부분을 위해서 document 모듈에서 추천시에 ip 주소가 글쓴이의 ip주소와 동일한지 체크하는 부분을 주석처리하기도 했구요

    그런데 정말 이상한건, 만약 그 부분이 문제라면
    마우스로 직접 클릭했을때도 동일하게 안되어야하는데
    오로지 jquery를 통해 click 했을때만 오류가 난다는게 좀 이해가 안가네요... ㅠㅠ
  • profile profile
    제가 현재까지 디버깅해본 결과

    jquery로 클릭하면 _SESSION['voted_document'][$document_srl 에는 false 값이 저장된다. 그러나 db에는 추천기록이 정상적으로 삽입된다.

    직접 마우스로 버튼를 클릭하면 별도 오류없이 모두 정상 작동한다(_SESSION['voted_document'][$document_srl 에도 1값이 정상 저장됨)

    입니다 허허...
  • profile profile
    어제 얘기했던 개발자도구부터 보죠. 댓글 작성 및 추천 시점에 실제로 어떤 요청과 응답이 오가는지...
  • profile profile

    우선 document 모듈부터 디버깅 해 보았습니다.

     

    function updateVotedCount($document_srl, $point = 1)
        {
            if($point > 0)
            {
                $failed_voted = 'failed_voted';
            }
            else
            {
                $failed_voted = 'failed_blamed';
            }

            // Return fail if session already has information about votes
            if($_SESSION['voted_document'][$document_srl])
            {
                debugPrint("이미 추천을 했다는 경우");
                return new BaseObject(-1, $failed_voted);
            }

            // Get the original document
            $oDocument = DocumentModel::getDocument($document_srl, false, false);

            // Pass if the author's IP address is as same as visitor's.
            //if($oDocument->get('ipaddress') == \RX_CLIENT_IP)
            //{
            //    $_SESSION['voted_document'][$document_srl] = false;
            //    return new BaseObject(-1, $failed_voted);
            //}

            // Get current member_srl
            $member_srl = MemberModel::getLoggedMemberSrl();

            // Check if document's author is a member.
            if($oDocument->get('member_srl'))
            {
                // Pass after registering a session if author's information is same as the currently logged-in user's.
                if($member_srl && $member_srl == abs($oDocument->get('member_srl')))
                {
                    debugPrint("Pass after registering a session if author's information is same as the currently logged-in user's.");
                    $_SESSION['voted_document'][$document_srl] = false;
                    return new BaseObject(-1, $failed_voted);
                }
            }

            // Use member_srl for logged-in members and IP address for non-members.
            $args = new stdClass();
            if($member_srl)
            {
                $args->member_srl = $member_srl;
            }
            else
            {
                $args->ipaddress = \RX_CLIENT_IP;
            }
            $args->document_srl = $document_srl;
            $output = executeQuery('document.getDocumentVotedLogInfo', $args);

            // Pass after registering a session if log information has vote-up logs
            if($output->data->count)
            {
                debugPrint("Pass after registering a session if log information has vote-up logs");
                $_SESSION['voted_document'][$document_srl] = false;
                return new BaseObject(-1, $failed_voted);
            }

            // Call a trigger (before)
            $trigger_obj = new stdClass;
            $trigger_obj->member_srl = $oDocument->get('member_srl');
            $trigger_obj->module_srl = $oDocument->get('module_srl');
            $trigger_obj->document_srl = $oDocument->get('document_srl');
            $trigger_obj->update_target = ($point < 0) ? 'blamed_count' : 'voted_count';
            $trigger_obj->point = $point;
            $trigger_obj->before_point = ($point < 0) ? $oDocument->get('blamed_count') : $oDocument->get('voted_count');
            $trigger_obj->after_point = $trigger_obj->before_point + $point;
            $trigger_obj->cancel = false;
            $trigger_output = ModuleHandler::triggerCall('document.updateVotedCount', 'before', $trigger_obj);
            if(!$trigger_output->toBool())
            {
                return $trigger_output;
            }
            
            // begin transaction
            $oDB = DB::getInstance();
            $oDB->begin();

            // Update the voted count
            if($trigger_obj->update_target === 'blamed_count')
            {
                $args->blamed_count = $trigger_obj->after_point;
                $output = executeQuery('document.updateBlamedCount', $args);
            }
            else
            {
                $args->voted_count = $trigger_obj->after_point;
                $output = executeQuery('document.updateVotedCount', $args);
            }
            if(!$output->toBool()) return $output;

            // Leave in the session information
            $_SESSION['voted_document'][$document_srl] = $trigger_obj->point;
            
            // Leave logs
            $args->point = $trigger_obj->point;
            $output = executeQuery('document.insertDocumentVotedLog', $args);
            if(!$output->toBool()) return $output;
            
            // Call a trigger (after)
            ModuleHandler::triggerCall('document.updateVotedCount', 'after', $trigger_obj);

            $oDB->commit();

            //remove document item from cache
            Rhymix\Framework\Cache::delete('document_item:' . getNumberingPath($document_srl) . $document_srl);

            // Return result
            $output = new BaseObject();
            if($trigger_obj->update_target === 'voted_count')
            {
                $output->setMessage('success_voted');
                $output->add('voted_count', $trigger_obj->after_point);
            }
            else
            {
                $output->setMessage('success_blamed');
                $output->add('blamed_count', $trigger_obj->after_point);
            }
            
            return $output;
        }

     

    이렇게 세션값을 false 로 만들어주는 조건문 마다 debugprint 를 해보았으나 그 결과는...

     


    [2021-07-12 11:38:18]

    Debug Entries
    =============
    None

     

    이네요. 그럼 모듈의 추천 부분에 의해 세션값이 false 로 고정되는건 아니라는것 같습니다 ㅠㅠ

  • profile profile
    [2021-07-12 11:38:18]

    Debug Entries
    =============
    None

    이 부분이 추천을 누른 부분이 맞는지 정확히 보셔야 합니다.

    라이믹스는 http POST요청과 get요청과 동시다발적으로 따로따로 기록하기 때문에 타이밍이 다를 수 있습니다.

    디버그 모드역시 file에 기록하는 방법을 사용하여 디버깅 하셔야 합니다.