यदि मेटा डेटा फ़ील्ड मान्य नहीं है, तो कस्टम पोस्ट प्रकार पोस्ट प्रकाशित न करें


12

मेरे पास एक कस्टम पोस्ट प्रकार (CPT) है जिसे कहा जाता है event। मेरे पास कई क्षेत्रों के साथ प्रकार के लिए एक मेटा बॉक्स है। मैं एक घटना को प्रकाशित करने से पहले कुछ क्षेत्रों को मान्य करना चाहूंगा। उदाहरण के लिए, यदि किसी घटना की तारीख निर्दिष्ट नहीं है, तो मैं एक सूचनात्मक त्रुटि संदेश प्रदर्शित करना चाहूंगा, भविष्य के संपादन के लिए घटना को बचा सकता हूं, लेकिन उस घटना को प्रकाशित होने से रोकें। क्या सभी आवश्यक जानकारी के बिना CPT पोस्ट के लिए 'लंबित' स्थिति इसके इलाज का सही तरीका है?

CPT फ़ील्ड्स सत्यापन करने और किसी पोस्ट को प्रकाशित होने से रोकने के लिए सबसे अच्छा अभ्यास क्या है, लेकिन इसे भविष्य के संपादन के लिए सहेजें।

बहुत धन्यवाद, दशा


आपको इस प्रश्न को याद दिलाने के लिए सौम्य नग्नता को अभी भी एक स्वीकृत उत्तर की आवश्यकता है ..;) यदि न तो आपके प्रश्न का उत्तर दिया गया है, तो कृपया अपने प्रश्न को अतिरिक्त टिप्पणियों के साथ अपने प्रश्न को अपडेट करने पर विचार करें, जिसे संबोधित नहीं किया गया है (या जहां आपको मदद की आवश्यकता हो सकती है, यदि लागू हो)।
t31os

जवाबों:


14

आप मामूली JQuery के हैक के साथ सभी को एक साथ सहेजने से पोस्ट को रोक सकते हैं और ग्राहक पक्ष या सर्वर पक्ष को अजाक्स के साथ सहेजने से पहले फ़ील्ड को मान्य कर सकते हैं:

सबसे पहले हम जमा / प्रकाशन कार्यक्रम पर कब्जा करने के लिए अपने जावास्क्रिप्ट को जोड़ते हैं और वास्तविक जमा करने से पहले अपने स्वयं के अजाक्स फ़ंक्शन को जमा करने के लिए इसका उपयोग करते हैं:

 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अपने पोस्ट प्रकार के लिए और क्लाइंट पक्ष पर मान्य करने के लिए केवल अपने पोस्ट प्रकार के लिए सत्यापन करने के लिए इसे थोड़ा बदल सकते हैं, लेकिन मैं सर्वर साइड पर पसंद करता हूं।


क्या ऐसा करने का कोई सर्वर-साइड तरीका नहीं है?
जेफ

1
यह एक सर्वर साइड तरीका है।
बैनटर्नट

1
शायद मैं कुछ गलत समझ रहा हूं। ऐसा लगता है कि आप जावास्क्रिप्ट का उपयोग करने के लिए PHP का उपयोग कर रहे हैं जो सत्यापन करता है। यह सर्वर साइड सत्यापन नहीं है। मैं वास्तव में समझ नहीं पा रहा हूँ कि कैसे pre_submit_validationफिट बैठता है।
जेफ

पहला my_publish_admin_hookब्लॉक पोस्ट सबमिशन क्लाइंट-साइड को इंटरसेप्ट करता है - लेकिन फिर यह सर्वर (पूर्व-आधिकारिक-इन pre_submit_validation) को एक AJAX कॉल करता है जो सर्वर-साइड सत्यापन करता है।
emc

1
यह अभी भी क्लाइंट-साइड सत्यापन है, भले ही यह सत्यापन करने के लिए AJAX का उपयोग कर रहा हो। किसी भी सत्यापन के लिए क्लाइंट को पहले स्थान पर जावास्क्रिप्ट को चलाना पड़ता है। हालाँकि ... मुझे अभी भी यह उत्तर पूर्व प्रस्तुत सत्यापन के लिए उपयोगी लगा। धन्यवाद!
cr0ybot

7

विधि के दो चरण हैं: पहला, अपने कस्टम मेटाबॉक्स फ़ील्ड डेटा (save_post पर हुक) को बचाने के लिए एक फ़ंक्शन, और दूसरा, उस नए पोस्ट_मेटा (जिसे आपने अभी बचाया है) को पढ़ने के लिए एक फ़ंक्शन, इसे मान्य करें, और इसका परिणाम संशोधित करें आवश्यक के रूप में बचत (भी save_post करने के लिए झुका, लेकिन पहले के बाद)। सत्यापनकर्ता फ़ंक्शन, यदि सत्यापन विफल रहता है, वास्तव में पोस्ट_स्टैटस को "लंबित" में बदल देता है, प्रभावी रूप से पोस्ट प्रकाशित होने से रोकता है।

चूंकि save_post फ़ंक्शन को बहुत अधिक कहा जाता है, प्रत्येक फ़ंक्शन के पास केवल तब निष्पादित करने के लिए चेक होते हैं जब उपयोगकर्ता को प्रकाशित करने का मतलब होता है, और केवल आपके कस्टम पोस्ट प्रकार (माइकोस्टाइपाइप) के लिए।

मैं आमतौर पर उपयोगकर्ता को यह जानने में मदद करने के लिए कुछ कस्टम सूचना संदेश भी जोड़ता हूं कि उनका पोस्ट प्रकाशित क्यों नहीं हुआ, लेकिन उन लोगों को यहां शामिल करने के लिए थोड़ा जटिल हो गया ...

मैंने इस सटीक कोड का परीक्षण नहीं किया है, लेकिन मैंने बड़े पैमाने पर कस्टम पोस्ट प्रकार के सेटअपों में जो कुछ किया है उसका एक सरलीकृत संस्करण है।

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

जब यूजर को "पब्लिश / अपडेट" बटन हिट होता है तो आपको अजाक्स पर अपने मेटा फील्ड वैल्यू की जांच / सत्यापन करना होगा। यहाँ मैं खाली मूल्य के लिए मेटा फ़ील्ड "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

बस यह जोड़ना चाहते थे कि पोस्ट वैरिएबल को पढ़ने के लिए, बैनटेनट के समाधान का उपयोग करके, आपको $_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 }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.