não publica postagem de tipo de postagem personalizada se um campo de metadados não for válido

11

Eu tenho um tipo de postagem personalizado (CPT) chamado event . Eu tenho uma caixa meta para o tipo com vários campos. Eu gostaria de validar alguns campos antes de publicar um evento. Por exemplo, se a data de um evento não for especificada, gostaria de exibir uma mensagem de erro informativa, salvar o evento para edição futura, mas impedir que esse evento seja publicado. O status "pendente" de uma postagem CPT sem todas as informações necessárias é o caminho certo para tratá-la?

Qual é a melhor prática para validar os campos de CPT e impedir que uma publicação seja publicada, mas salve-a para edição futura.

Muito obrigado, Dasha

    
por dashaluna 25.04.2011 / 15:35

4 respostas

13

Você pode impedir que a postagem seja salva junto com pequenos hacks do JQuery e validar os campos antes de salvar no lado do cliente ou no lado do servidor com ajax:

primeiro, adicionamos nosso JavaScript para capturar o evento submit / publish e o usamos para enviar nossa própria função ajax antes do envio real:

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

então criamos a função para fazer a validação real:

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

sempre é possível alterar um pouco para fazer a validação apenas para o tipo de postagem adicionando uma verificação condicional à função my_publish_admin_hook para o tipo de postagem e para validar no lado do cliente, mas eu prefiro no lado do servidor. / p>     

por Bainternet 26.04.2011 / 14:20
6

Existem dois passos para o método: primeiro, uma função para salvar seus dados de campo metabox personalizados (hooked to save_post), e segundo, uma função para ler aquele novo post_meta (que você acabou de salvar), validá-lo e modificar o resultado de salvar conforme necessário (também ligado a save_post, mas após o primeiro). A função de validador, se a validação falhar, na verdade muda o post_status de volta para "pendente", impedindo efetivamente que o post seja publicado.

Como a função save_post é chamada muito, cada função tem verificações para serem executadas somente quando o usuário quiser publicar, e apenas para o tipo de postagem personalizado (mycustomtype).

Normalmente, também adiciono algumas mensagens de aviso personalizadas para ajudar o usuário a saber por que a postagem não foi publicada, mas foi um pouco complicado incluir aqui ...

Eu não testei este código exato, mas é uma versão simplificada do que eu fiz em configurações de tipo de postagem personalizadas em grande escala.

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

Para vários campos de metabox, basta adicionar mais marcadores de conclusão e recuperar mais post_meta e fazer mais testes.

    
por somatic 25.04.2011 / 23:24
1

você precisa verificar / validar seu valor de meta-campo em ajax, ou seja, quando o usuário clicar no botão "Publicar / Atualizar". Aqui estou validando o produto woocommerce tendo meta campo "product_number" para valor vazio.

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

Depois disso, adicione a função de manipulador ajax,

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();
}
    
por Mohan Dere 01.10.2015 / 13:31
0

Só queria adicionar isso para ler as variáveis post, usando a solução da Bainternet, você terá que analisar a string em $_POST['form_data'] usando PHP parse_str function (apenas para poupar algum tempo de pesquisa).

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

Então você pode acessar cada variável usando apenas $varname . Por exemplo, se você tem um campo meta chamado "my_meta", você o acessaria assim:

$vars = parse_str ( $_POST['form_data'] ) 
if ( $my_meta == "something" ) { // do something }
    
por Agus 22.08.2011 / 08:28