未保存自定义发布类型的元数据

时间:2014-05-24 作者:Mike

我正在构建一个自定义插件,在保存自定义帖子类型的元数据时遇到了问题。这些框在编辑器中正确显示,但单击“发布”或“保存草稿”时,输入的值不会保留。

我已经在下面粘贴了我的代码片段。我已经学习了一些教程,并在这里查看了几个问题,但看起来我已经正确地学习了所有内容,我不知道哪里出了问题。我相信这是显而易见的。

任何帮助都将不胜感激。

自定义帖子类型

// Register the Jobs post type
function fg_registerJobsPostType() {
    // Floodgate Jobs Post Type
    $fg_postType = \'fg_job\';

    $jobsLabels = array(
        \'name\'               => _x( \'Floodgate Jobs\', \'post type general name\', \'\' ),
        \'singular_name\'      => _x( \'Floodgate Job\', \'post type singular name\', \'\' ),
        \'menu_name\'          => _x( \'Floodgate Jobs\', \'admin menu\', \'\' ),
        \'name_admin_bar\'     => _x( \'Floodgate Job\', \'add new on admin bar\', \'\' ),
        \'add_new\'            => __( \'Add New\', \'Floodgate Job\', \'\' ),
        \'add_new_item\'       => __( \'Add New Job\', \'\' ),
        \'new_item\'           => __( \'New Job\', \'\' ),
        \'edit_item\'          => __( \'Edit Job\', \'\' ),
        \'view_item\'          => __( \'View Job\', \'\' ),
        \'all_items\'          => __( \'All Jobs\', \'\' ),
        \'search_items\'       => __( \'Search Jobs\', \'\' ),
        \'parent_item_colon\'  => __( \'Parent Jobs:\', \'\' ),
        \'not_found\'          => __( \'No Jobs found.\', \'\' ),
        \'not_found_in_trash\' => __( \'No Jobs found in Trash.\', \'\' ),
    );

    $jobsArgs = array(
        \'labels\'             => $jobsLabels,
        \'public\'             => true,
        \'publicly_queryable\' => true,
        \'show_ui\'            => true,
        \'show_in_menu\'       => true,
        \'query_var\'          => true,
        \'rewrite\'            => array( \'slug\' => \'fg_job\' ),
        \'capability_type\'    => \'post\',
        \'has_archive\'        => true,
        \'hierarchical\'       => false,
        \'menu_position\'      => 5,
        \'supports\'           => array( \'editor\', \'custom-fields\' )        
    );

    register_post_type( \'fg_job\', $jobsArgs );
}
add_action( \'init\', \'fg_registerJobsPostType\' );
还有代谢箱

// Register the Jobs Metaboxes
function fg_registerJobsMetabox() {
    /* Add meta boxes on the \'add_meta_boxes\' hook. */
    add_action( \'add_meta_boxes\', \'fg_addJobMetaboxes\' );

    /* Save post meta on the \'save_post\' hook. */
    add_action( \'wp_insert_post_data\', \'fg_saveJobsMeta\', 10, 2);
}
add_action( \'load-post.php\', \'fg_registerJobsMetabox\' );
add_action( \'load-post-new.php\', \'fg_registerJobsMetabox\' );

// Build the display components for the Jobs Metaboxes
function fg_addJobMetaboxes() {
    add_meta_box(
        \'fg_jobDesc\',      // Unique ID
        esc_html__( \'Job Description\', \'Business Cards\' ),    // Title
        \'fg_jobDescMetabox\',   // Callback function
        \'fg_job\',         // Admin page (or post type)
        \'side\',         // Context
        \'default\'         // Priority
    );

    add_meta_box(
        \'fg_jobStatus\',      // Unique ID
        esc_html__( \'Job Status\', \'Printing\' ),    // Title
        \'fg_jobStatusMetabox\',   // Callback function
        \'fg_job\',         // Admin page (or post type)
        \'side\',         // Context
        \'default\'         // Priority
    );

    add_meta_box(
        \'fg_jobDueDate\',      // Unique ID
        esc_html__( \'Due Date\', \'\' ),    // Title
        \'fg_jobDueDateMetabox\',   // Callback function
        \'fg_job\',         // Admin page (or post type)
        \'side\',         // Context
        \'default\'         // Priority
    );

    add_meta_box(
        \'fg_jobPriority\',      // Unique ID
        esc_html__( \'Job Priority\', \'\' ),    // Title
        \'fg_jobPriorityMetabox\',   // Callback function
        \'fg_job\',         // Admin page (or post type)
        \'side\',         // Context
        \'default\'         // Priority
    );
}
和保存功能

function fg_verifyMetaNonce($metaKey) {
    return  (isset($_POST[$metaKey . \'_nonce\']) && wp_verify_nonce( $_POST[$metaKey . \'_nonce\'], basename(__FILE__)));
}

function fg_saveMetaData($postID, $metaKey, $newMetaValue) {
    /* Get the meta value of the custom field key. */
    $metaValue = get_post_meta( $postID, $metaKey, true );

    /* If a new meta value was added and there was no previous value, add it. */
    if ( $newMetaValue && \'\' == $metaValue )
        update_post_meta( $postID, $metaKey, $newMetaValue, true );

    /* If the new meta value does not match the old value, update it. */
    elseif ( $newMetaValue && $newMetaValue != $metaValue )
        update_post_meta( $postID, $metaKey, $newMetaValue );

    /* If there is no new meta value but an old value exists, delete it. */
    elseif ( \'\' == $newMetaValue && $metaValue )
        delete_post_meta( $postID, $metaKey, $metaValue );
}


// Save the Jobs Metadata
function fg_saveJobsMeta($postID, $post) {
    /* Get the post type object. */
    $postType = get_post_type_object( $post->postType );

/* Check if the current user has permission to edit the post. */
if ( !current_user_can( $postType->cap->edit_post, $postID ) )
    return $postID;

    // Save the Job Description
    $metaKey = \'fg_jobDesc\';

        /* Verify the nonce before proceeding. */
        if ( verifyMetaNonce($metaKey) )
            return $postID;

        /* Get the posted data and sanitize it for use as an HTML class. */
        $jobDesc = ( isset( $_POST[$metaKey] ) ? sanitize_text_field( $_POST[$metaKey] ) : \'\' );

    fg_saveMetaData($postID, $metaKey, $jobDesc);

    // Save the Job Status
    $metaKey = \'fg_jobStatus\';

        /* Verify the nonce before proceeding. */
        if ( verifyMetaNonce($metaKey) )
            return $postID;

        /* Get the posted data and sanitize it for use as an HTML class. */
        $jobStatus = ( isset( $_POST[$metaKey] ) ? sanitize_text_field( $_POST[$metaKey] ) : \'\' );

        fg_saveMetaData($postID, $metaKey, $jobStatus);

    // Save the Job Description
    $metaKey = \'fg_jobDueDate\';

        /* Verify the nonce before proceeding. */
        if ( verifyMetaNonce($metaKey) )
            return $postID;

        /* Get the posted data and sanitize it for use as an HTML class. */
        $jobDueDate = ( isset( $_POST[$metaKey] ) ? sanitize_text_field( $_POST[$metaKey] ) : \'\' );

        fg_saveMetaData($postID, $metaKey, $jobDueDate);

    // Save the Job Description
    $metaKey = \'fg_jobPriority\';

        /* Verify the nonce before proceeding. */
        if ( verifyMetaNonce($metaKey) )
            return $postID;

        /* Get the posted data and sanitize it for use as an HTML class. */
        $jobPriority = ( isset( $_POST[$metaKey] ) ? sanitize_text_field( $_POST[$metaKey] ) : \'\' );

        fg_saveMetaData($postID, $metaKey, $jobPriority);
}

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

正如对这个问题的评论所表明的,这基本上是一堆垃圾(我的话,不是他们的话)。有许多拼写错误和反向布尔检查。这是一场噩梦。

我设法让代码正常工作,我不喜欢没有答案的问题,所以我想自上而下地解决这些错误,并指出我最终得到的解决方案。

第一个问题是注册元数据库:

// Register the Jobs Metaboxes
function fg_registerJobsMetabox() {
    /* Add meta boxes on the \'add_meta_boxes\' hook. */
    add_action( \'add_meta_boxes\', \'fg_addJobMetaboxes\' );

    /* Save post meta on the \'save_post\' hook. */
    add_action( \'wp_insert_post_data\', \'fg_saveJobsMeta\', 10, 2); // <- THIS IS THE ERROR
}
add_action( \'load-post.php\', \'fg_registerJobsMetabox\' );
add_action( \'load-post-new.php\', \'fg_registerJobsMetabox\' );
在这种情况下add_action() 呼叫不正确。使用时wp_insert_post_data hook,my的函数参数fg_saveJobsMeta() 函数返回的值不正确。

将此切换到add_action( \'save_post\', \'fg_saveJobsMeta\', 10, 2) 已解决此错误

问题区域二下一个问题存在于fg_saveJobsMeta($postID, $post) 功能:

function fg_saveJobsMeta($postID, $post) {
    /* Get the post type object. */
    $postType = get_post_type_object( $post->postType ); // <- THIS IS THE ERROR

    /* Check if the current user has permission to edit the post. */
    if ( !current_user_can( $postType->cap->edit_post, $postID ) )
        return $postID;
    [...]
}
的价值$postType was always being set to null, 因为$post->postType 不正确。应更改为$post->post_typepost_type 是实际post对象上的字段。

问题区域三下一个问题是fg_saveJobsMeta() 功能:

// Save the Job Description
$metaKey = \'fg_jobDesc\';

    /* Verify the nonce before proceeding. */
    if ( verifyMetaNonce($metaKey) ) // <- THIS IS THE ERROR
        return $postID;

    /* Get the posted data and sanitize it for use as an HTML class. */
    $jobDesc = ( isset( $_POST[$metaKey] ) ? sanitize_text_field( $_POST[$metaKey] ) : \'\' );

fg_saveMetaData($postID, $metaKey, $jobDesc);
这里有两个问题。

  • verifyMetaNonce($metaKey) 是错误的功能
正确的函数调用是fg_verifyMetaNonce($metaKey). 函数名的前缀是为了减少与其他插件和/或主题的冲突。

布尔检查是向后的如果fg_verifyMetaNonce($metaKey) 退货true (意味着我们有一个有效的nonce值),函数将返回$postID 和退出,但应该保存。

在这种情况下,正确的调用是if (!fg_verifyMetaNonce($metaKey). 只有当nonce值验证失败时,才会退出保存过程。

这些错误重复了好几次(对于我识别的每个自定义字段都是一次)。

在解决问题的过程中,我发现我的代码中有其他问题,但我没有在原始问题上发布。

在设置实际的metabox UI元素时出现了一些错误(再次针对每个自定义字段重复)。我复制了以下字段之一:

// Generate the Job Description Metaboxes
function fg_jobDescMetabox() { // <- ERROR HERE
    wp_nonce_field( \'updating_job_meta\', \'fg_jobDesc_nonce\'); ?> // <- ERROR HERE

    <p>
        // ERROR HERE
        <input class="widefat" type="text" name="fg_jobDesc" id="fg_jobDesc"
        value="<?php echo esc_attr( get_post_meta( $post->ID, \'fg_jobDesc\', true ) ); ?>" />
    </p>
<?php }
正确的代码如下:

// Generate the Job Description Metaboxes
function fg_jobDescMetabox($object, $box) {
// ^ This function actually receives two arguments.
    wp_nonce_field( \'updating_job_meta\', \'fg_jobDesc_nonce\', true); ?>
    // ^ The wp_nonce_field() call needed a third boolean argument
    //   Without this argument, the nonce value was never set on the request.

    <p>
        <input class="widefat" type="text" name="fg_jobDesc" id="fg_jobDesc"
        value="<?php echo esc_attr( get_post_meta( $object->ID, \'fg_jobDesc\', true ) ); ?>" />
        // ^ the global `$post` variable is null here, so using it did me no good.
        //   I need to use the $object parameter passed into the function instead. 
    </p>
<?php }
如上所述,我的每个自定义字段都重复了这个问题,因此我需要在几个地方修复它。

我已经仔细查看了那些有可怕bug的代码,并将其与我的工作版本进行了多次比较。我相信这涵盖了两个文件之间的所有问题和差异。

结束

相关推荐

Metabox内的WP_LIST_TABLE未处理提交

我正在尝试显示WP_List_table 在metabox中。metabox用于名为service 已注册到名为office. 表列包含操作分类法的输入字段,并允许我将其他数据链接到每个单独的分类法术语。我不认为我试图将其用于自定义帖子类型编辑屏幕上的自定义分类法这一事实是相关的。我只是为了清楚起见才提到。现在的情况是,在我单击自定义帖子类型编辑屏幕上的发布/更新按钮之前,一切看起来都很好。如果WP_List_Table 具有批量操作,它将重定向回/wp-admin/edit.php 页面中,如果我删除了