메타 데이터 필드가 유효하지 않은 경우 맞춤 게시물 유형 게시물을 게시하지 않습니다


12

이라는 맞춤 게시물 유형 (CPT)이 event있습니다. 여러 필드가있는 유형의 메타 상자가 있습니다. 이벤트를 게시하기 전에 일부 필드의 유효성을 검사하고 싶습니다. 예를 들어, 이벤트 날짜가 지정되지 않은 경우 유익한 오류 메시지를 표시하고 나중에 편집 할 수 있도록 이벤트를 저장하지만 해당 이벤트가 공개되지 않도록하십시오. 필요한 모든 정보가없는 CPT 게시물의 '보류 중'상태가 올바른 처리 방법입니까?

CPT 필드 유효성 검사를 수행하고 게시물이 게시되는 것을 방지하지만 나중에 편집 할 수 있도록 저장하는 가장 좋은 방법은 무엇입니까?

많은 감사합니다, Dasha


이 질문에 아직 답변이 필요하다는 것을 알려주십시오..;) 질문에 대한 답변이없는 경우, 해결되지 않은 사항 (또는 해당되는 경우 도움이 필요한 곳)을 자세히 설명하는 추가 의견으로 질문을 업데이트하십시오.
t31os

답변:


14

ajax를 사용하여 클라이언트 측 또는 서버 측에 저장하기 전에 사소한 JQuery 해킹과 함께 게시물이 모두 저장되지 않도록하고 필드의 유효성을 검사 할 수 있습니다.

먼저 JavaScript를 추가하여 제출 / 게시 이벤트를 캡처하고 실제 제출 전에 자체 ajax 함수를 제출하는 데 사용합니다.

 add_action('wp_print_scripts','my_publish_admin_hook');

function my_publish_admin_hook(){
if (is_admin()){
        ?>
        <script language="javascript" type="text/javascript">
            jQuery(document).ready(function() {
                jQuery('#post').submit(function() {

                    var form_data = jQuery('#post').serializeArray();
                    form_data = jQuery.param(form_data);
                    var data = {
                        action: 'my_pre_submit_validation',
                        security: '<?php echo wp_create_nonce( 'pre_publish_validation' ); ?>',
                        form_data: form_data
                    };
                    jQuery.post(ajaxurl, data, function(response) {
                        if (response.indexOf('True') > -1 || response.indexOf('true') > -1 || response === true ||  response) {
                            jQuery('#ajax-loading').hide();
                            jQuery('#publish').removeClass('button-primary-disabled');
                            return true;
                        }else{
                            alert("please correct the following errors: " + response);
                            jQuery('#ajax-loading').hide();
                            jQuery('#publish').removeClass('button-primary-disabled');
                            return false;
                        }
                    });
                    return false;
                });
            });
        </script>
        <?php
    }
}

그런 다음 실제 유효성 검사를 수행하는 함수를 만듭니다.

add_action('wp_ajax_my_pre_submit_validation', 'pre_submit_validation');
function pre_submit_validation(){
    //simple Security check
    check_ajax_referer( 'pre_publish_validation', 'security' );

    //do your validation here
    //all of the form fields are in $_POST['form_data'] array
    //and return true to submit: echo 'true'; die();
    //or your error message: echo 'bal bla bla'; die();
}

게시물 유형에 my_publish_admin_hook대해 기능 검사를 추가 하고 클라이언트 측에서 유효성을 검사하기 위해 조건부 검사를 추가하여 게시물 유형에 대해서만 유효성 검사를 수행하도록 항상 약간 변경할 수 있지만 서버 쪽을 선호합니다.


이를 수행 할 서버 측 방법이 없습니까?
Jeff

1
이것은 서버 측 방법입니다.
Bainternet

1
어쩌면 나는 무언가를 오해하고 있을지도 모른다. 유효성 검사를 수행하는 JavaScript를 렌더링하기 위해 PHP를 사용하는 것 같습니다. 그것은 서버 측 유효성 검사가 아닙니다. 나는 실제로 어떻게 pre_submit_validation맞는지 이해하지 못한다 .
Jeff

첫 번째 my_publish_admin_hook블록은 제출 후 클라이언트 측을 차단하지만 pre_submit_validation서버 측 유효성 검사를 수행 하는 AJAX 호출을 서버에 제출합니다 (사전 제출 ).
emc

1
이것은 AJAX를 사용하여 유효성 검사를 수행하더라도 클라이언트 측 유효성 검사입니다. 유효성 검사를 수행하려면 클라이언트가 먼저 JavaScript를 실행해야합니다. 그러나 ... 나는 여전히이 답변이 제출 전 유효성 검사에 유용하다는 것을 알았습니다. 감사!
cr0ybot

7

이 방법에는 두 가지 단계가 있습니다. 첫째, 사용자 정의 메타 박스 필드 데이터를 저장하는 함수 (sav_post에 후크 됨)와 둘째, 새 post_meta (방금 저장 한)를 읽고 확인하고 결과를 수정하는 함수입니다. 필요에 따라 저장합니다 (또한 save_post에 연결되었지만 첫 번째 이후에). 유효성 검사에 실패하면 유효성 검사기 기능은 실제로 post_status를 "pending"으로 다시 변경하여 게시물이 효과적으로 게시되지 않도록합니다.

save_post 함수가 많이 호출되기 때문에 각 함수는 사용자가 게시 할 때만 사용자 정의 게시 유형 (mycustomtype)에 대해서만 실행되도록 검사합니다.

또한 일반적으로 사용자가 자신의 게시물이 게시되지 않은 이유를 알 수 있도록 몇 가지 사용자 지정 알림 메시지를 추가하지만 여기에 포함하기에는 약간 복잡합니다 ...

이 정확한 코드를 테스트하지는 않았지만 대규모 사용자 정의 포스트 유형 설정에서 수행 한 작업의 단순화 된 버전입니다.

add_action('save_post', 'save_my_fields', 10, 2);
add_action('save_post', 'completion_validator', 20, 2);

function save_my_fields($pid, $post) {
    // don't do on autosave or when new posts are first created
    if ( ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) || $post->post_status == 'auto-draft' ) return $pid;
    // abort if not my custom type
    if ( $post->post_type != 'mycustomtype' ) return $pid;

    // save post_meta with contents of custom field
    update_post_meta($pid, 'mymetafield', $_POST['mymetafield']);
}


function completion_validator($pid, $post) {
    // don't do on autosave or when new posts are first created
    if ( ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) || $post->post_status == 'auto-draft' ) return $pid;
    // abort if not my custom type
    if ( $post->post_type != 'mycustomtype' ) return $pid;

    // init completion marker (add more as needed)
    $meta_missing = false;

    // retrieve meta to be validated
    $mymeta = get_post_meta( $pid, 'mymetafield', true );
    // just checking it's not empty - you could do other tests...
    if ( empty( $mymeta ) ) {
        $meta_missing = true;
    }

    // on attempting to publish - check for completion and intervene if necessary
    if ( ( isset( $_POST['publish'] ) || isset( $_POST['save'] ) ) && $_POST['post_status'] == 'publish' ) {
        //  don't allow publishing while any of these are incomplete
        if ( $meta_missing ) {
            global $wpdb;
            $wpdb->update( $wpdb->posts, array( 'post_status' => 'pending' ), array( 'ID' => $pid ) );
            // filter the query URL to change the published message
            add_filter( 'redirect_post_location', create_function( '$location','return add_query_arg("message", "4", $location);' ) );
        }
    }
}

여러 메타 박스 필드의 경우 완료 마커를 추가하고 더 많은 post_meta를 검색하고 더 많은 테스트를 수행하십시오.


1

사용자가 "Publish / Update"버튼을 눌렀을 때 ajax에서 메타 필드 값을 확인 / 확인해야합니다. 여기에 빈 값에 대해 "product_number"메타 필드가있는 woocommerce 제품의 유효성을 검사하고 있습니다.

add_action('admin_head-post.php','ep_publish_admin_hook');
add_action('admin_head-post-new.php','ep_publish_admin_hook');

function ep_publish_admin_hook(){
    global $post;
    if ( is_admin() && $post->post_type == 'product' ){
        ?>
        <script language="javascript" type="text/javascript">
            (function($){
                jQuery(document).ready(function() {

                    jQuery('#publish').click(function() {
                        if(jQuery(this).data("valid")) {
                            return true;
                        }

                        //hide loading icon, return Publish button to normal
                        jQuery('#publishing-action .spinner').addClass('is-active');
                        jQuery('#publish').addClass('button-primary-disabled');
                        jQuery('#save-post').addClass('button-disabled');

                        var data = {
                            action: 'ep_pre_product_submit',
                            security: '<?php echo wp_create_nonce( "pre_publish_validation" ); ?>',
                            'product_number': jQuery('#acf-field-product_number').val()
                        };
                        jQuery.post(ajaxurl, data, function(response) {

                            jQuery('#publishing-action .spinner').removeClass('is-active');
                            if ( response.success ){
                                jQuery("#post").data("valid", true).submit();
                            } else {
                                alert("Error: " + response.data.message );
                                jQuery("#post").data( "valid", false );

                            }
                            //hide loading icon, return Publish button to normal
                            jQuery('#publish').removeClass('button-primary-disabled');
                            jQuery('#save-post').removeClass('button-disabled');
                        });
                        return false;
                    });
                });
            })(jQuery);
        </script>
        <?php
    }
}

그 후 아약스 핸들러 기능 추가,

add_action('wp_ajax_ep_pre_product_submit', 'ep_pre_product_submit_func');
function ep_pre_product_submit_func() {
    //simple Security check
    check_ajax_referer( 'pre_publish_validation', 'security' );

    if ( empty( $_POST['product_number'] ) || empty( $_POST['file_attachment'] ) ) {
         $data = array(
            'message' => __('Please enter part number and specification document.'),
        );
        wp_send_json_error( $data );
    }
    wp_send_json_success();
}

0

Bainternet의 솔루션을 사용하여 포스트 변수를 읽으려면 추가하고 싶었으므로 $_POST['form_data']PHP parse_str기능 을 사용하여 문자열을 구문 분석해야합니다 (연구 시간을 절약하기 위해).

$vars = parse_str( $_POST['form_data'] );

그런 다음을 사용하여 각 변수에 액세스 할 수 있습니다 $varname. 예를 들어, "my_meta"라는 메타 필드가있는 경우 다음과 같이 액세스하십시오.

$vars = parse_str ( $_POST['form_data'] ) 
if ( $my_meta == "something" ) { // do something }
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.