사용자 정의 필드를 저장할 때 유효성 검사 및 오류 처리를 추가 하시겠습니까?


27

게시물 유형에 사용자 정의 필드를 정의하는 함수가 있습니다. 필드가 "subhead"라고 가정하십시오.

게시물이 저장되면 입력에 대한 유효성 검사를 수행하고 필요한 경우 게시물 편집 화면에 오류 메시지를 표시하려고합니다. 다음과 같은 것 :

// Handle post updating
function wpse_update_post_custom_values($post_id, $post) {

    // Do some checking...
    if($_POST['subhead'] != 'value i expect') {

        // Add an error here
        $errors->add('oops', 'There was an error.');

    }

    return $errors;

} 
add_action('save_post','wpse_update_post_custom_values',1,2);

이것을 save_post 액션에 연결하려고하는데 오류를 처리하는 방법을 알 수 없습니다. 함수에 전달 된 오류 객체가없는 것 같습니다. 내 자신의 WP_Error obj를 만들고 반환하면 게시물 편집 페이지에서 오류를 내뿜는 메커니즘이 존중되지 않습니다.

현재 맞춤 메타 상자에 페이지 오류 메시지가 표시되어 있지만 이상적이지는 않습니다. WP가 일반적으로 표시하는 것과 같이 크고 빨간색의 최상위 오류가 발생합니다.

어떤 아이디어?

최신 정보:

@Denis의 답변을 바탕으로 몇 가지 다른 시도를했습니다. Wordpress는 save_post 프로세스 중에 경로 재 지정을 수행하여 전역을 표시하기 전에 오류를 발생시키기 때문에 오류를 전역으로 저장하지 못했습니다.

결국 메타 필드에 저장했습니다. 이것의 문제는 그것들을 지우거나 다른 페이지로 이동할 때 사라지지 않기 때문에 admin_footer에 연결된 다른 함수를 추가하여 오류를 지우는 것입니다.

너무 일반적인 (업데이트 업데이트)에 대한 오류 처리가 어수선하다고 생각하지 않았습니다. 내가 명백한 것을 놓치고 있거나 이것이 최선의 접근법입니까?

// Handle post updating
function wpse_5102_update_post_custom_values($post_id, $post) {

    // To keep the errors in
    $errors = false;

    // Do some validation...
    if($_POST['subhead'] != 'value i expect') {

        // Add an error here
        $errors .= 'whoops...there was an error.';

    }

    update_option('my_admin_errors', $errors);

    return;

} 
add_action('save_post','wpse_5102_update_post_custom_values',1,2);


// Display any errors
function wpse_5102_admin_notice_handler() {

    $errors = get_option('my_admin_errors');

    if($errors) {

        echo '<div class="error"><p>' . $errors . '</p></div>';

    }   

}
add_action( 'admin_notices', 'wpse_5102_admin_notice_handler' );


// Clear any errors
function wpse_5102__clear_errors() {

    update_option('my_admin_errors', false);

}
add_action( 'admin_footer', 'wpse_5102_clear_errors' );

좋은 질문. admin_footer통지 핸들러 함수의 끝에서 오류를 지우면 후크를 제거 할 수 있다고 생각합니다 . 일을 조금만 단순화합니다.
Geert

양식 필드를 다시 채우는 방법 (유효하지 않은 데이터가 있음)을 어떻게 처리합니까?
Geert

기본적인 질문이 있습니다. 이 Wordpress PHP 파일은 무엇입니까?

@Karen 이것은 사용자 정의 플러그인 파일 또는 functions.php에 있습니다.
MathSmath

나는 명백한 것을 놓칠 수도 있지만 update_option('my_admin_errors', false);끝에 if 문 직후 에 실행하는 것이 약간 더 효율적 wpse_5102_admin_notice_handler()입니까?
앤드류 오드리

답변:


6

오류를 클래스 또는 전역으로, 일시적 또는 메타로 저장하고 POST 요청에 대한 관리자 알림에 표시하십시오. WP에는 플래시 메시지 핸들러가 없습니다.


이 방향으로 나를 가리켜 주셔서 감사합니다! 메타를 사용하여 오류를 저장하는 결과를 얻었습니다. 전역이나 속성으로 수행하려고하는 데 문제가 있었기 때문입니다. 내가 지금하고있는 방법을 설명하기 위해 지금 답변을 업데이트하고 있습니다 ... 이것이 당신이 제안한 종류인지 아닌지, 더 나은 방법이 있는지 알려주십시오.
MathSmath

그런 것 같아요 어쨌든 세션 변수에 저장하십시오. 이를 통해 여러 작성자가 동시에 게시물을 편집 할 수 있습니다. :-) 또한 옵션에 false를 저장할 수 없다고 생각합니다. 빈 문자열을 대신 저장하십시오.
Denis de Bernardy

6

두 명의 사용자가 동시에 편집 할 때 이상한 효과가 발생하지 않으므로 세션을 사용하는 것이 좋습니다. 이것이 내가하는 일입니다.

세션은 워드 프레스로 시작되지 않습니다. 따라서 플러그인, functions.php 또는 wp-config.php에서 세션시작 해야합니다 .

if (!session_id())
  session_start();

게시물을 저장할 때 세션에 오류 및 알림을 추가하십시오.

function my_save_post($post_id, $post) {
   if($something_went_wrong) {
     //Append error notice if something went wrong
     $_SESSION['my_admin_notices'] .= '<div class="error"><p>This or that went wrong</p></div>';
     return false; //might stop processing here
   }
   if($somthing_to_notice) {  //i.e. successful saving
     //Append notice if something went wrong
     $_SESSION['my_admin_notices'] .= '<div class="updated"><p>Post updated</p></div>';
   }

   return true;
} 
add_action('save_post','my_save_post');

통지 및 오류를 인쇄 한 후 세션에서 메시지를 정리하십시오.

function my_admin_notices(){
  if(!empty($_SESSION['my_admin_notices'])) print  $_SESSION['my_admin_notices'];
  unset ($_SESSION['my_admin_notices']);
}
add_action( 'admin_notices', 'my_admin_notices' );

세션 버전 수정 : 세션 변수를 처음 사용할 때. = 만 사용하지 마십시오. = = 디버깅을 켜면 이유를 확인할 수 있습니다.

3
나도이 일을했지만, 당신이 그런 사람들과 같은 광범위한 청중에게 플러그인을 출시하면 사람들이 당신을 싫어하게 될 것입니다. Wordpress는 상태 비 저장으로 설계되어 세션이 필요하지 않으므로 세션을 인스턴스화하지 않으며 일부 이상한 서버 설정으로 인해 세션이 중단 될 수 있습니다. 세션 대신 일시적 API-codex.wordpress.org/Transients_API 를 사용하면 호환성이 유지됩니다. 여기서 이것을하지 않는 이유를 표시 할 가치가 있다고 생각했습니다.
pospi

@pospi 이것은 get_option 및 update_option 함수의 원래 사용과 비슷한 문제가있는 것으로 보입니다. 그래서 해결책은 현재 사용자의 ID를 키에 추가하는 것입니다.
Gazillion

그래, 그것은 완전히 작동합니다! 사용자를 고유하게 식별하기 위해 무언가를 추가하는 한 로그인 한 사용자간에 메시지가 섞이지 않도록합니다 (:
pospi

5

과도기 를 사용 하는 pospi제안 에 기초 하여 다음을 생각해 냈습니다. 유일한 문제는 다른 메시지가 있는 곳 아래에 메시지를 넣을 후크가 없다는 것입니다. 그래서 jQuery 해킹을 수행해야했습니다.h2

먼저, save_post(또는 유사한) 핸들러로 인해 오류 메시지를 저장하십시오 . 60 초의 짧은 수명을 제공하기 때문에 리디렉션이 발생할 수있는 시간이 충분합니다.

if($has_error)
{
  set_transient( "acme_plugin_error_msg_$post_id", $error_msg, 60 );
}

그런 다음 다음 페이지로드시 해당 오류 메시지를 검색하여 표시하십시오. 또한 두 번 표시되지 않도록 삭제합니다.

add_action('admin_notices', 'acme_plugin_show_messages');

function acme_plugin_show_messages()
{
  global $post;
  if ( false !== ( $msg = get_transient( "acme_plugin_error_msg_{$post->ID}" ) ) && $msg) {
    delete_transient( "acme_plugin_error_msg_{$post->ID}" );
    echo "<div id=\"acme-plugin-message\" class=\"error below-h2\"><p>$msg</p></div>";
  }
}

admin_notices기본 페이지 컨텐츠가 생성되기 전에 실행 되므로 다른 사후 편집 메시지가있는 위치에 통지가 없으므로이 jQuery를 사용하여 이동해야합니다.

jQuery('h2').after(jQuery('#acme-plugin-message'));

게시물 ID는 임시 이름의 일부이므로 여러 사용자가 동일한 게시물을 동시에 편집하는 경우를 제외하고 대부분의 다중 사용자 환경에서 작동합니다.


"게시물 ID가 임시 이름의 일부이므로"에 대해 자세히 설명해 주시겠습니까? 이 기술을 사용하여 오류 메시지를 처리하는 클래스를 만들었지 만 생성자가 user_ID를 전달해야합니다. 키를 해시 할 때 임시 API가 user_id를 사용합니까? (코덱이 언급하지 않기 때문에 묻습니다)
Gazillion

아니요, 수동으로 추가 할 수 있습니다. 위에서 게시 한 코드에서 과도의 이름은입니다 acme_plugin_error_msg_POSTID. 당신은 그런 식으로 사용자 ID를 추가 할 수 있습니다 acme_plugin_error_msg_POSTID_USERID.
Joshua Coady

2

save_post실행될 때 이미 데이터베이스에 게시물을 저장했습니다.

WordPress 핵심 코드,보다 구체적으로 wp-includes/post.phpupdate_post()기능을 살펴보면 요청을 데이터베이스에 저장하기 전에 요청을 가로 챌 수있는 기본 제공 방법이 없습니다.

그러나, 우리는 연결할 수 pre_post_update사용 header()get_post_edit_link()저장되는 게시물을 방지하기 위해.

<?php

/**
*   Performs validation before saving/inserting custom post type
*/
function custom_post_site_save($post_id, $post_data) {
    // If this is just a revision, don't do anything.
    if (wp_is_post_revision($post_id))
        return;

    if ($post_data['post_type'] == 'my_custom_post_type') {
        // Deny post titles with less than 5 characters
        if (strlen($post_data['post_title'] < 5)) {
            header('Location: '.get_edit_post_link($post_id, 'redirect'));
            exit;
        }
    }
}
add_action( 'pre_post_update', 'custom_post_site_save', 10, 2);

사용자에게 무엇이 잘못되었는지 알리려면 다음 요점을 확인하십시오. https://gist.github.com/Luc45/09f2f9d0c0e574c0285051b288a0f935


처음으로 게시하거나 게시물을 업데이트하는지 여부에 관계없이 유효성 검사를 완벽하게 처리합니다. 당신은 저에게 많은 시간과 노력을 절약했습니다.
Zade

1

Javascript를 사용하여 필드를 검증하지 않는 이유는 무엇입니까? 이것이 최선의 방법이라고 생각합니다.


제안 해 주셔서 감사합니다! (간단히하기 위해) 질문에서 제외 한 것은 파일 업로드 오류를 처리하려고하므로 서버 측이어야합니다. 그래도 제안 주셔서 감사합니다!
MathSmath

자바 스크립트 유효성 검사로 일부 공격을 막을 수는 없으며 서버 측 유효성 검사가 유일한 보안 방법입니다. 또한 워드 프레스는 사용자 데이터를 검증 할 수있는 훌륭한 도구를 제공합니다. 그러나 서버로 데이터를 보내기 전에 일부 값을 확인하면 서버에서 시간을 절약 할 수 있습니다 ^^
nderambure

1

위의 스크립트를 사용하려고 할 때 이상한 문제가 발생했습니다. 사후 업데이트 후 편집 화면에 두 개의 메시지가 표시됩니다. 하나는 이전 저장의 내용 상태와 현재의 내용을 보여줍니다. 예를 들어 게시물을 올바르게 저장 한 다음 오류를 발생시키는 경우 첫 번째는 "error"이고 두 번째는 "ok"입니다. 같은 시간에 생성됩니다. 스크립트를 변경하고 하나의 메시지 (예 : "오류") 만 추가하면 "error"로 하나의 업데이트를 시작한 다음 "ok"로 다른 업데이트를 시작하면 "error"메시지가 유지됩니다 (두 번째로 표시됨). 제거하려면 다시 "ok"로 저장해야합니다. 나는 정말로 무엇이 잘못되었는지 알지 못하고 3 개의 다른 로컬 서버에서 테스트했으며 각 서버에 동일한 문제가 있습니다.


위에서 언급 한 더 간단한 두 번째 버전의 스크립트에 대해 더 많은 테스트를 수행했으며 "오류"메시지가 실제로 세션 배열에 추가되면 편집 화면에 표시되는 것 같습니다. 메시지가없고 (모든 것이 "ok") 이전 메시지가 오류 인 경우 화면에 나타납니다. 이상한 점은 저장시 (캐시되지 않은) 생성됩니다-오류 메시지 본문에서 date ()를 사용하여 확인했습니다. 나는 지금 완전히 혼란 스럽다.
jlub

좋아, 다른 사람이 머리에서 머리카락을 뽑는 경우-Wordpress 개정 시스템이 문제 (어쩌면 어떤 종류의 버그입니까?)였습니다. 나는 그것을 비활성화했고 이제는 모든 것이 잘되었습니다.

0

게시물 편집 화면에 플래시 오류 처리 기능을 추가하고 필수 필드가 채워질 때까지 게시물이 게시되지 않도록하는 플러그인을 작성했습니다.

https://github.com/interconnectit/required-fields

포스트 필드를 필수로 만들 수 있지만 API를 사용하여 사용자 정의 가능한 오류 메시지 및 유효성 검사 기능과 함께 필요한 사용자 정의 필드를 만들 수도 있습니다. 기본적으로 필드가 비어 있는지 확인합니다.


github에 문제가 있으면 언제든지 추가하십시오. 사용할 수있는 추가 필터가 있으므로 API를 조금 더 잘 문서화해야합니다.
sanchothefat
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.