nu publica postarea de tip custom post type dacă un câmp de meta date nu este valid

25 apr. 2011, 16:35:01
Vizualizări: 19K
Voturi: 14

Am un custom post type (CPT) numit event. Am o meta box pentru acest tip cu mai multe câmpuri. Aș dori să validez unele câmpuri înainte de a publica un eveniment. De exemplu, dacă data unui eveniment nu este specificată, aș dori să afișez un mesaj de eroare informativ, să salvez evenimentul pentru editare viitoare, dar să împiedic publicarea acelui eveniment. Este statusul 'pending' pentru un CPT fără toate informațiile necesare modalitatea corectă de a-l trata?

Care este cea mai bună practică pentru a valida câmpurile unui CPT și a împiedica publicarea unei postări, dar totuși să o salvezi pentru editare ulterioară.

Mulțumesc mult, Dasha

1
Comentarii

O remarcă prietenoasă pentru a-ți aminti că această întrebare încă are nevoie de un răspuns acceptat.. ;) Dacă niciunul dintre răspunsuri nu ți-a rezolvat problema, te rugăm să consideri actualizarea întrebării cu comentarii suplimentare care să detalieze ce nu a fost abordat (sau unde ai putea avea nevoie de ajutor, dacă este cazul).

t31os t31os
28 iul. 2011 12:14:26
Toate răspunsurile la întrebare 4
6
15

Puteți opri salvarea postării complet cu mici hack-uri JQuery și puteți valida câmpurile înainte de salvare pe partea de client sau server cu ajutorul ajax:

mai întâi adăugăm JavaScript-ul nostru pentru a captura evenimentul de submit/publish și îl folosim pentru a trimite propria noastră funcție ajax înainte de trimiterea efectivă:

 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("Vă rugăm să corectați următoarele erori: " + response);
                            jQuery('#ajax-loading').hide();
                            jQuery('#publish').removeClass('button-primary-disabled');
                            return false;
                        }
                    });
                    return false;
                });
            });
        </script>
        <?php
    }
}

apoi creăm funcția pentru a face validarea efectivă:

add_action('wp_ajax_my_pre_submit_validation', 'pre_submit_validation');
function pre_submit_validation(){
    //simplă verificare de securitate
    check_ajax_referer( 'pre_publish_validation', 'security' );

    //faceți validarea aici
    //toate câmpurile din formular sunt în array-ul $_POST['form_data']
    //și returnați true pentru a trimite: echo 'true'; die();
    //sau mesajul de eroare: echo 'bal bla bla'; die();
}

puteți oricând să o modificați puțin pentru a face validarea doar pentru tipul dumneavoastră de postare prin adăugarea unei verificări condiționale în funcția my_publish_admin_hook pentru tipul dumneavoastră de postare și pentru a valida pe partea de client, dar eu prefer pe partea de server.

26 apr. 2011 15:20:59
Comentarii

Nu există o metodă pe partea de server pentru a face asta?

Jeff Jeff
5 iul. 2014 00:58:15

Aceasta este o metodă pe partea de server pentru a o face.

Bainternet Bainternet
5 iul. 2014 07:59:18

Poate înțeleg greșit ceva. Se pare că folosești PHP doar pentru a randă JavaScript care face validarea. Aceasta nu este validare pe partea de server. Nu înțeleg cu adevărat cum se potrivește pre_submit_validation în acest context.

Jeff Jeff
7 iul. 2014 19:42:26

Primul bloc my_publish_admin_hook interceptează trimiterea postării pe partea de client - dar apoi face un apel AJAX către server (înainte de trimiterea oficială în pre_submit_validation) care efectuează validarea pe server.

emc emc
3 mar. 2015 03:46:12

Aceasta este în continuare validare pe partea de client, chiar dacă folosește AJAX pentru a efectua validarea. Clientul trebuie să ruleze JavaScript-ul în primul rând pentru ca orice validare să aibă loc.

Totuși... am găsit acest răspuns util pentru validarea pre-trimitere. Mulțumesc!

cr0ybot cr0ybot
15 aug. 2016 21:35:00

Pacat dacă nu există o metodă nativă în WordPress pentru a face un lucru atât de tipic

Fanky Fanky
24 oct. 2019 15:02:11
Arată celelalte 1 comentarii
0

Există doi pași în această metodă: mai întâi, o funcție pentru a salva datele câmpului personalizat din metabox (legată la save_post), și al doilea, o funcție pentru a citi acea post_meta nouă (pe care tocmai ai salvat-o), a o valida și a modifica rezultatul salvării după cum este necesar (de asemenea legată la save_post, dar după prima). Funcția de validare, dacă validarea eșuează, schimbă de fapt post_status înapoi la "pending", prevenind efectiv publicarea postării.

Deoarece funcția save_post este apelată frecvent, fiecare funcție are verificări pentru a se executa doar când utilizatorul intenționează să publice și doar pentru tipul tău personalizat de postare (mycustomtype).

De asemenea, de obicei adaug câteva mesaje personalizate pentru a ajuta utilizatorul să înțeleagă de ce postarea lui nu a fost publicată, dar acelea au devenit prea complicate pentru a fi incluse aici...

Nu am testat acest cod exact, dar este o versiune simplificată a ceea ce am făcut în configurații complexe de tipuri personalizate de postări.

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

function save_my_fields($pid, $post) {
    // nu executa la autosave sau când postările noi sunt create prima dată
    if ( ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) || $post->post_status == 'auto-draft' ) return $pid;
    // întrerupe dacă nu este tipul meu personalizat
    if ( $post->post_type != 'mycustomtype' ) return $pid;

    // salvează post_meta cu conținutul câmpului personalizat
    update_post_meta($pid, 'mymetafield', $_POST['mymetafield']);
}

function completion_validator($pid, $post) {
    // nu executa la autosave sau când postările noi sunt create prima dată
    if ( ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) || $post->post_status == 'auto-draft' ) return $pid;
    // întrerupe dacă nu este tipul meu personalizat
    if ( $post->post_type != 'mycustomtype' ) return $pid;

    // inițializează marcatorul de completare (adaugă mai multe după nevoie)
    $meta_missing = false;

    // preia meta pentru validare
    $mymeta = get_post_meta( $pid, 'mymetafield', true );
    // doar verifică dacă nu este gol - poți face și alte teste...
    if ( empty( $mymeta ) ) {
        $meta_missing = true;
    }

    // la încercarea de publicare - verifică completarea și intervine dacă este necesar
    if ( ( isset( $_POST['publish'] ) || isset( $_POST['save'] ) ) && $_POST['post_status'] == 'publish' ) {
        // nu permite publicarea dacă oricare dintre acestea este incomplet
        if ( $meta_missing ) {
            global $wpdb;
            $wpdb->update( $wpdb->posts, array( 'post_status' => 'pending' ), array( 'ID' => $pid ) );
            // filtrează URL-ul de redirect pentru a schimba mesajul de publicare
            add_filter( 'redirect_post_location', create_function( '$location','return add_query_arg("message", "4", $location);' ) );
        }
    }
}

Pentru mai multe câmpuri de metabox, adaugă pur și simplu mai mulți marcatori de completare și preia mai multă post_meta și efectuează mai multe teste...

26 apr. 2011 00:24:03
0

trebuie să verifici/validezi valoarea câmpului meta prin ajax, adică atunci când utilizatorul apasă butonul "Publică/Actualizează". Aici validez un produs WooCommerce care are câmpul meta "product_number" pentru valoare goală.

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

                        //ascunde iconița de încărcare, readuce butonul Publică la 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("Eroare: " + response.data.message );
                                jQuery("#post").data( "valid", false );

                            }
                            //ascunde iconița de încărcare, readuce butonul Publică la normal
                            jQuery('#publish').removeClass('button-primary-disabled');
                            jQuery('#save-post').removeClass('button-disabled');
                        });
                        return false;
                    });
                });
            })(jQuery);
        </script>
        <?php
    }
}

După aceea, adaugă funcția de gestionare ajax,

add_action('wp_ajax_ep_pre_product_submit', 'ep_pre_product_submit_func');
function ep_pre_product_submit_func() {
    //simplă verificare de securitate
    check_ajax_referer( 'pre_publish_validation', 'security' );

    if ( empty( $_POST['product_number'] ) || empty( $_POST['file_attachment'] ) ) {
         $data = array(
            'message' => __('Te rog să introduci numărul părții și documentul de specificație.'),
        );
        wp_send_json_error( $data );
    }
    wp_send_json_success();
}
1 oct. 2015 14:31:47
0

Doar voiam să adaug că pentru a citi variabilele postate, folosind soluția lui Bainternet, va trebui să analizați șirul din $_POST['form_data'] utilizând funcția PHP parse_str (doar pentru a vă economisi timpul de cercetare).

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

Apoi puteți accesa fiecare variabilă folosind direct $varname. De exemplu, dacă aveți un câmp meta numit "my_meta", l-ați accesa astfel:

$vars = parse_str ( $_POST['form_data'] ) 
if ( $my_meta == "something" ) { // faci ceva }
22 aug. 2011 09:28:00