meta veri alanı geçerli değilse özel yayın türü yayını yayınlama


12

Denilen özel bir yazı türüm (CPT) var event. Birkaç alanı olan tür için bir meta kutusu var. Bir etkinliği yayınlamadan önce bazı alanları doğrulamak istiyorum. Örneğin, bir etkinliğin tarihi belirtilmezse, bilgilendirici bir hata mesajı görüntülemek, etkinliği ileride düzenlemek üzere kaydetmek istiyorum, ancak o etkinliğin yayınlanmasını önlüyorum. Gerekli tüm bilgileri içermeyen bir CPT yayını için "beklemede" durumu, iletiyi işlemek için doğru yol mu?

CPT alanlarını doğrulamak ve bir yayının yayınlanmasını önlemek için en iyi uygulama hangisidir, ancak gelecekteki düzenleme için saklayın.

Çok teşekkürler, Dasha


Bu soruyu hatırlatmak için nazik bir dürtünün hala kabul edilmiş bir cevaba ihtiyacı var;
t31os

Yanıtlar:


14

Küçük JQuery saldırıları ile birlikte gönderinin tümünü kaydetmesini durdurabilir ve istemci tarafında veya sunucu tarafında ajax ile kaydetmeden önce alanları doğrulayabilirsiniz:

ilk olarak, gönder / yayınla etkinliğini yakalamak için JavaScript’imizi ekler ve gerçek gönderilmeden önce kendi ajax işlevimizi göndermek için kullanırız:

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

o zaman gerçek doğrulamayı yapmak için fonksiyon yaratırız:

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();
}

Her zaman yazı türünüz için my_publish_admin_hookişlev için koşullu bir denetim ekleyerek ve istemci tarafında doğrulamak için koşullu bir denetim ekleyerek yalnızca yazı türü için doğrulama yapmak için biraz değiştirebilirsiniz ama sunucu tarafında tercih ederim.


Bunu yapmanın bir sunucu tarafı yolu yok mu?
Jeff

1
Bu bir sunucu tarafı yoludur.
Bainternet

1
Belki bir şeyi yanlış anlıyorum. Doğrulama yapan JavaScript'i oluşturmak için yalnızca PHP kullandığınız anlaşılıyor. Bu sunucu tarafı doğrulaması değil. Ne kadar pre_submit_validationuyduğunu gerçekten anlamıyorum .
Jeff

İlk my_publish_admin_hookblok, gönderim sonrası istemci tarafını durdurur - ancak pre_submit_validationsunucu tarafında doğrulama yapan sunucuya bir AJAX çağrısı yapar (resmi olarak teslim etme ).
emc

1
Doğrulamayı yapmak için AJAX kullanıyor olsa bile, bu hala istemci tarafı doğrulamadır. İstemcinin, herhangi bir doğrulamanın yapılabilmesi için JavaScript'i öncelikle çalıştırması gerekir. Ancak ... yine de bu cevabı gönderim öncesi onaylama için yararlı buldum. Teşekkürler!
cr0ybot

7

Yöntemin iki adımı vardır: birincisi, özel meta kutu alan verilerinizi kaydetme işlevi (save_post'a bağlı) ve ikincisi, yeni post_meta'yı (yeni kaydettiğiniz) okuma, doğrulama ve sonucunu değiştirme işlevi gerektiğinde kaydetme (ayrıca save_post'a bağlanır, ancak ilkinden sonra). Doğrulama işlevi başarısız olursa, aslında post_status öğesini doğrudan "beklemede" olarak değiştirir ve gönderinin yayınlanmasını etkili bir şekilde önler.

Save_post işlevi çok fazla çağrıldığından, her işlev yalnızca kullanıcı yayınlamak istediğinde ve yalnızca özel yazı türünüz (özelim türü) için yürütülecek denetimlere sahiptir.

Ayrıca, kullanıcının gönderilerinin neden yayınlanmadığını bilmesine yardımcı olmak için genellikle bazı özel bildirim mesajları ekliyorum, ancak bunlar buraya dahil etmek biraz karmaşıklaştı ...

Bu tam kodu test etmedim, ancak büyük ölçekli özel yazı tipi kurulumlarında yaptığımın basitleştirilmiş bir sürümü.

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);' ) );
        }
    }
}

Birden çok meta kutu alanı için daha fazla tamamlama işareti ekleyin ve daha fazla post_meta alın ve daha fazla test yapın.


1

ajax'ta meta alan değerinizi kontrol etmeniz / doğrulamanız gerekir; örneğin, kullanıcı "Yayınla / Güncelle" düğmesine bastığında. Burada boş değer için meta alanı "product_number" olan woocommerce ürün doğrulamak.

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

Bundan sonra ajax işleyici işlevi ekleyin,

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'in çözümünü kullanarak post değişkenlerini okumak için bunu eklemek istedim, $_POST['form_data']PHP parse_strişlevini kullanarak dizeyi ayrıştırmanız gerekecek (sadece size biraz zaman kazandırmak için).

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

Sonra her bir değişkeni sadece kullanarak erişebilirsiniz $varname. Örneğin, "my_meta" adlı bir meta alanınız varsa buna şu şekilde erişirsiniz:

$vars = parse_str ( $_POST['form_data'] ) 
if ( $my_meta == "something" ) { // do something }
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.