传递帖子ID和为不同帖子类型保存自定义元框时,SAVE_POST函数冲突

时间:2011-04-23 作者:Chris_O

将Post save函数添加到save\\u Post action挂钩时,它们相互冲突。

2种不同的自定义帖子类型,带有2个不同的(每种帖子类型一个)自定义元框。

我只包括其中一个元框的代码。另一个非常相似,每个都可以单独工作,但不能一起工作。

“register\\u metabox\\u cb”回调函数:

function c3m_video_meta() {
    add_meta_box(\'_c3m_video_embed\', __(\'Enter Video Embed Code In the Box Below\') , \'c3m_video_embed\', \'video\', \'normal\', \'low\');
    }
将元框添加到后期编辑屏幕:
function c3m_video_embed($post) {
    global $post;
    wp_nonce_field(__FILE__,\'video_nonce\');
    $embed-code = get_post_meta($post->ID, \'_embed-code\', true);
    echo \'<input type="text" name="_embed-code" value=""\' . $embed-code . \'" class="widefat" />\' ; 
    }
保存功能:
  function c3m_save_video_meta( $post_id , $post ) { 

            if ( !wp_verify_nonce( $_POST [ \'video_nonce\' ], __FILE__ ) ) { return $post ->ID; 
            }
            if ( !current_user_can( \'edit_post\' , $post ->ID )) return $post ->ID; 
            $c3m_video_embed-code [ \'_embed-code\' ] = $_POST [ \'_embed-code\' ]; 
                        foreach ( $c3m_video_embed-code as $key => $value ) { 
                        if ( $post ->post_type == \'revision\' ) return ; 

                        $value = implode( \',\' , ( array ) $value );
                        if (get_post_meta( $post ->ID, $key , FALSE)) { 
                        update_post_meta( $post ->ID, $key , $value ); } else { 
                        add_post_meta( $post ->ID, $key , $value ); } if (! $value ) delete_post_meta( $post ->ID, $key ); 
                        }
}
动作挂钩:

add_action( \'admin_menu\' , \'c3m_video_meta\' );

add_action( \'save_post\' , \'c3m_save_video_meta\' , 1, 2);

这很好,也很好,但当我将另一个元框添加到不同的帖子类型,并在保存帖子时使用类似的函数(不同的函数名、nonce名称和键)时,我会出现以下错误:

注意:未定义索引:_embed-code in/Applications/MAMP/htdocs/wordpress/wp content/plugins/iew custom functions/iew custom functions。php在线181

警告:无法修改标题信息-标题已由/Applications/MAMP/htdocs/wordpress/wp-content/plugins/iew-custom-functions/iew-custom-functions.php:181)中的/Applications/MAMP/htdocs/wordpress/wp-includes/pluggable发送。php在线897

未定义的\\u embed-code是在保存不包含\\u embed-code变量的帖子时使用的。

由于错误消息会根据我尝试保存的帖子类型进行反转,因此我认为这两个(2个不同的)保存功能都添加到了save\\u post操作中。在保存普通帖子时,也会添加它们。如果我只使用了其中的一个保存功能,那么在保存普通帖子时就不会出现错误。

而不是这个问题"Fix My Code" 问题我希望答案包含添加自定义元框和使用各种nonce方法的方式和原因。当然,我可以使用“更多字段”插件,但我宁愿学习用自定义内容类型定制编辑后屏幕的最佳方法。

我使用了相同的代码和方法将多个元框添加到一个自定义的帖子类型中,它一直运行良好。

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

在做了更多的研究后,我发现:

而不是挂起add_meta_box 函数到admin_menu 它应该连接到add_meta_boxesupdate_post_meta 函数,而不是使用wp_nonce_field 可以使用esc_attrstrip_tags

  • 要将帖子id传递给save meta box函数,您不需要包含额外的$post变量,您必须在save函数中为帖子类型添加一个条件状态,您必须调用global $post 在save函数中,添加两个元框的新代码更加简单:
    add_action( \'add_meta_boxes\', \'c3m_sponsor_meta\' );
    
    function c3m_sponsor_meta() {
        add_meta_box( \'c3m_sponsor_url\', \'Sponsor URL Metabox\', \'c3m_sponsor_url\', \'sponsor\', \'side\', \'high\' );
    }
    
    function c3m_sponsor_url( $post ) {
        $sponsor_url = get_post_meta( $post->ID, \'_sponsor_url\', true);
        echo \'Please enter the sponsors website link below\';
        ?>
            <input type="text" name="sponsor_url" value="<?php echo esc_attr( $sponsor_url ); ?>" />
        <?php
    }
    
    add_action( \'save_post\', \'c3m_save_sponsor_meta\' );
    
    function c3m_save_sponsor_meta( $post_id ) {
        global $post;
        if( $post->post_type == "sponsor" ) {
            if (isset( $_POST ) ) {
                update_post_meta( $post_ID, \'_sponsor_url\', strip_tags( $_POST[\'sponsor_url\'] ) );
            }
        }
    }
    
    add_action( \'add_meta_boxes\', \'c3m_video_meta\' );        
    
    function c3m_video_meta() {
        add_meta_box( \'c3m_video_embed_code\', \'Video Embed Code Meta Box\', \'c3m_video_embed_code\', \'video\', \'normal\', \'high\' );
    }
    
    function c3m_video_embed_code( $post ) {
        $embed_code = get_post_meta( $post->ID, \'_embed_code\', true);
        echo \'Please enter the video embed code below\';
        ?>
            <input type="text" name="embed_code" value="<?php echo esc_attr( $embed_code ); ?>" />
        <?php
    }
    
    add_action( \'save_post\', \'c3m_save_video_meta\' );
    
    function c3m_save_video_meta( $post_id ) {
        global $post;
        if( $post->post_type == "video" ) {
            if (isset( $_POST ) ) {
                update_post_meta( $post_ID, \'_embed_code\', strip_tags( $_POST[\'embed_code\'] ) );
            }
        }
    }
    

  • SO网友:Milo

    不使用wp\\u nonce\\u字段,可以使用esc\\u attr和strip\\u标记清理数据

    我没有遵循转义数据而不是使用nonce的逻辑?wordpress上给出的示例。org使用nonce来验证意图,并在插入数据之前对其进行转义。这两件事有什么关系?

    SO网友:helgatheviking

    你不需要全局$post,你完全可以将其传递到函数中。

    我有两个不同的save\\u post操作,一个用于快速编辑,另一个用于同一post类型上的metabox,最后我将它们组合在一起,以消除关于不同nonce的未定义索引通知。由于这两个项覆盖相同的数据,我使用了相同的nonce生成名称。

    无论如何,我会考虑将save\\u post函数合并到1。。。或者在检查nonce之前检查post类型。

    add_action( \'save_post\' , \'c3m_save_meta\' , 20, 2); //moved priority to later. you had priority 1 so is possible that WP actions were happening after your code
    
    function c3m_save_meta( $post_id , $post ) {   
    
       // verify if this is an auto save routine. If it is our form has not been submitted, so we dont want to do anything
       if ( defined(\'DOING_AUTOSAVE\') && DOING_AUTOSAVE ) return $post_id;
    
       //don\'t save if only a revision
       if ( $post->post_type == \'revision\' ) return $post_id;   
    
       // Check permissions
       if ( \'page\' == $post->post_type ) {
        if ( !current_user_can( \'edit_page\', $post_id ) ) return $post_id;
       } else {
        if ( !current_user_can( \'edit_post\', $post_id ) ) return $post_id;
       }      
    
      //save video post meta
      if( $post->post_type == "video" && wp_verify_nonce( $_POST [ \'video_nonce\' ], __FILE__ )) {
         if (isset( $_POST[\'_embed_code\'] ) ) {
            update_post_meta( $post_ID, \'_embed_code\', esc_attr( $_POST[\'embed_code\'] ) );
         }
      }
    
      //save sample bacon post meta
       if( $post->post_type == "bacon" && wp_verify_nonce( $_POST [ \'bacon_nonce\' ], __FILE__ )) {
          if (isset( $_POST[\'_bacon_code\'] ) ) {
            update_post_meta( $post_ID, \'_bacon_code\', esc_attr( $_POST[\'bacon_code\'] ) );
          }
       }
    }
    
    也可以对两个元数据库使用相同的nonce名称。无法对此安全性发表评论,但对我来说似乎没问题,因为WP似乎在快速编辑和常规编辑模式下对\\u wpnance做了同样的事情。WP似乎也没有为每个代谢箱单独设置一个nonce。

    function c3m_save_meta( $post_id , $post ) {   
           if(!wp_verify_nonce( $_POST [ \'c3m_nonce\' ], __FILE__ )) return $post_id; //change both nonces to name=c3m_nonce
    
           // verify if this is an auto save routine. If it is our form has not been submitted, so we dont want to do anything
           if ( defined(\'DOING_AUTOSAVE\') && DOING_AUTOSAVE ) return $post_id;  
    
           //don\'t save if only a revision
           if ( $post->post_type == \'revision\' ) return $post_id; 
    
           // Check permissions
           if ( \'page\' == $post->post_type ) {
            if ( !current_user_can( \'edit_page\', $post_id ) ) return $post_id;
           } else {
            if ( !current_user_can( \'edit_post\', $post_id ) ) return $post_id;
           }      
    
          //save video post meta
          if( $post->post_type == "video") {
             if (isset( $_POST[\'_embed_code\'] ) ) {
                update_post_meta( $post_ID, \'_embed_code\', esc_attr( $_POST[\'embed_code\'] ) );
             }
          }
    
          //save sample bacon post meta
           if( $post->post_type == "bacon" && wp_verify_nonce( $_POST [ \'bacon_nonce\' ], __FILE__ )) {
              if (isset( $_POST[\'_bacon_code\'] ) ) {
                update_post_meta( $post_ID, \'_bacon_code\', esc_attr( $_POST[\'bacon_code\'] ) );
              }
           }
        }
    

    结束

    相关推荐

    无法在自定义构建的Metabox中保存自定义分类术语

    我大致遵循了tutorial here 关于如何创建“自定义分类输入面板”。我正在使用自定义帖子类型homes 还有一种自定义分类法beds (用于记录一所房子的床位数)。我已经在下拉菜单中显示了分类术语,但无法在保存帖子时保存它们。我开始只是发布旨在保存术语的代码,但意识到我应该发布创建和显示元盒的代码,以用于上下文。自定义帖子类型名称为“homes”,自定义分类名称为“beds”。分类法是分层的(我认为这并不重要,但我可能错了)。//adding metaboxes for the homes pos