如果元数据字段无效,则不发布自定义POST类型的POST

时间:2011-04-25 作者:dashaluna

我有一个自定义帖子类型(CPT),名为event. 我有一个带有多个字段的类型的元框。我想在发布事件之前验证一些字段。例如,如果未指定事件的日期,我希望显示一条信息性错误消息,请保存事件以供将来编辑,但防止发布该事件。没有所有必要信息的CPT帖子的“待定”状态是否是正确的处理方式?

进行CPT字段验证并阻止发布帖子,但将其保存以供将来编辑的最佳做法是什么。

非常感谢,Dasha

4 个回复
最合适的回答,由SO网友:Bainternet 整理而成

您可以使用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 功能用于您的帖子类型,并在客户端进行验证,但我更喜欢在服务器端进行验证。

SO网友:somatic

该方法有两个步骤:第一,一个用于保存自定义metabox字段数据的函数(钩住以保存\\u post),第二,一个用于读取新post\\u meta(刚刚保存)、验证它并根据需要修改保存结果的函数(也钩住以保存\\u post,但在第一个之后)。如果验证失败,validator函数实际上会将post\\u状态改回“挂起”,从而有效阻止发布帖子。

由于save\\u post函数被多次调用,因此每个函数都有检查,仅在用户想要发布时执行,并且仅针对您的自定义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\\u meta并进行更多测试。。

SO网友:Mohan Dere

您必须在ajax上检查/验证您的元字段值,即当用户点击“发布/更新”按钮时。在这里,我正在验证woocommerce产品的元字段“product\\u 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处理函数,

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

SO网友:Agus

只是想添加它来读取post变量,使用Bainternet的解决方案,您必须在$_POST[\'form_data\'] 使用PHPparse_str 功能(只是为了节省您一些研究时间)。

$vars = parse_str( $_POST[\'form_data\'] );
然后,只需使用$varname. 例如,如果您有一个名为“my\\u meta”的元字段,您可以这样访问它:

$vars = parse_str ( $_POST[\'form_data\'] ) 
if ( $my_meta == "something" ) { // do something }

结束

相关推荐

Comment form validation

如何设置注释字段的验证规则?我更改了评论者姓名/电子邮件/主页onmouseover和onblur的值(我使用它而不是标签-因此如果字段为空,它会显示“您的电子邮件”、“您的主页”等)。问题是,在提交时,它会在主页字段中提交此文本(因为它没有验证,而不像电子邮件字段,如果您输入了除[email protected]).如何验证主页字段?