อย่าเผยแพร่โพสต์ประเภทโพสต์ที่กำหนดเองถ้าเขตข้อมูลเมตาไม่ถูกต้อง


12

ฉันมีประเภทโพสต์ที่กำหนดเอง (CPT) eventที่เรียกว่า ฉันมีเมตาบ็อกสำหรับประเภทที่มีหลายฟิลด์ ฉันต้องการตรวจสอบความถูกต้องของฟิลด์ก่อนที่จะเผยแพร่กิจกรรม ตัวอย่างเช่นหากไม่ระบุวันที่ของเหตุการณ์ฉันต้องการแสดงข้อความแสดงข้อผิดพลาดให้บันทึกเหตุการณ์สำหรับการแก้ไขในอนาคต แต่ป้องกันเหตุการณ์นั้นไม่ให้เผยแพร่ สถานะ 'รอดำเนินการ' สำหรับการโพสต์ CPT โดยไม่มีข้อมูลที่จำเป็นทั้งหมดเป็นวิธีที่เหมาะสมในการจัดการหรือไม่

มีวิธีปฏิบัติที่ดีที่สุดในการตรวจสอบความถูกต้องของฟิลด์ CPT และป้องกันไม่ให้โพสต์เผยแพร่ แต่บันทึกไว้เพื่อการแก้ไขในอนาคต

ขอบคุณมาก Dasha


เขยิบเบา ๆ เพื่อเตือนคุณคำถามนี้ยังต้องการคำตอบที่ยอมรับได้ .. ;) หากไม่มีคำตอบตอบคำถามของคุณโปรดพิจารณาอัปเดตคำถามของคุณด้วยความคิดเห็นเพิ่มเติมซึ่งมีรายละเอียดที่ไม่ได้รับการแก้ไข (หรือที่คุณอาจต้องการความช่วยเหลือ
t31os

คำตอบ:


14

คุณสามารถหยุดการโพสต์บันทึกทั้งหมดพร้อมกับแฮ็ก JQuery เล็กน้อยและตรวจสอบความถูกต้องของเขตข้อมูลก่อนที่จะบันทึกในฝั่งไคลเอ็นต์หรือฝั่งเซิร์ฟเวอร์ด้วย ajax:

ก่อนอื่นเราเพิ่ม 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
บางทีฉันอาจเข้าใจผิดบางอย่าง ดูเหมือนว่าคุณเพิ่งใช้ PHP เพื่อสร้างจาวาสคริปต์ซึ่งทำการตรวจสอบ นั่นไม่ใช่การตรวจสอบด้านเซิร์ฟเวอร์ ฉันไม่เข้าใจความpre_submit_validationเหมาะสมของมันอย่างไร
Jeff

ครั้งแรกที่my_publish_admin_hookบล็อกไม่ส่งตัดโพสต์ฝั่งไคลเอ็นต์ - แต่มันก็ทำให้การโทร AJAX เพื่อเซิร์ฟเวอร์ (pre-อย่างเป็นทางการส่งในpre_submit_validation) ที่การตรวจสอบการดำเนินการด้านเซิร์ฟเวอร์
emc

1
นี่เป็นการตรวจสอบฝั่งไคลเอ็นต์แม้ว่าจะใช้ AJAX เพื่อตรวจสอบความถูกต้องก็ตาม ลูกค้าจะต้องเรียกใช้ JavaScript ในสถานที่แรกเพื่อให้การตรวจสอบใด ๆ เกิดขึ้น อย่างไรก็ตาม ... ฉันยังพบว่าคำตอบนี้มีประโยชน์สำหรับการตรวจสอบความถูกต้องก่อนส่ง ขอบคุณ!
cr0ybot

7

มีสองขั้นตอนในวิธีการ: ขั้นแรกให้ฟังก์ชั่นเพื่อบันทึกข้อมูลฟิลด์ metabox แบบกำหนดเองของคุณ (เชื่อมต่อกับ save_post) และที่สองฟังก์ชั่นเพื่ออ่าน post_meta ใหม่ (ซึ่งคุณเพิ่งบันทึกไว้) ตรวจสอบและแก้ไขผลลัพธ์ บันทึกตามความจำเป็น (รวมถึง save_post ด้วย แต่หลังจากครั้งแรก) ฟังก์ชันตัวตรวจสอบความถูกต้องหากการตรวจสอบล้มเหลวจริง ๆ แล้วเปลี่ยน post_status กลับไปเป็น "รอดำเนินการ" จริง ๆ แล้วป้องกันไม่ให้โพสต์ถูกเผยแพร่อย่างมีประสิทธิภาพ

เนื่องจากฟังก์ชั่น 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);' ) );
        }
    }
}

สำหรับเขตข้อมูล metabox หลายแห่งเพียงเพิ่มเครื่องหมายความสมบูรณ์มากขึ้นและดึง post_meta เพิ่มเติมและทำการทดสอบเพิ่มเติม ..


1

คุณต้องตรวจสอบ / ตรวจสอบค่าเมตาฟิลด์ของคุณในอาแจ็กซ์เช่นเมื่อผู้ใช้กดปุ่ม "เผยแพร่ / อัปเดต" ที่นี่ฉันกำลังตรวจสอบผลิตภัณฑ์ woocommerce ที่มีเขตข้อมูลเมตา "product_number" สำหรับค่าว่าง

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
    }
}

หลังจากนั้นเพิ่มฟังก์ชัน ajax handler

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']ใช้parse_strฟังก์ชันPHP (เพื่อประหยัดเวลาในการค้นคว้า)

$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.