具有自定义POST类型下拉选项的管理元数据在保存后不更新选择的输入

时间:2018-09-26 作者:Gianfabio Pezzolla

我正在尝试为wp构建一个小插件,为自定义帖子类型页面添加一个按钮http://example.com/events 有一个指向另一个自定义帖子类型页面的链接,我可以从管理页面的下拉菜单中选择。

metabox显示正确,但更新页面时未保存所选选项。

metabox dropdwon menu closed

metabox dropdwon menu closed

这是我的代码:

class eca_metabox {

    public function __construct()
  {

        add_action( \'add_meta_boxes\', array( $this, \'eca_add_meta_box\' ) );
        add_action( \'save_post\', array( $this, \'save\' ), 10, 2 );

    }

    public function eca_add_meta_box()
  {

        add_meta_box(
      \'eca-meta\',
          \'Scegli a quale corso deve linkare questo evento\',
          array(
        $this,
        \'eca_meta_box_function\'
      ),
          \'tribe_events\',
          \'normal\',
          \'high\'
    );

    }

    public function eca_meta_box_function( $post )
  {

    wp_nonce_field( \'eca_nonce_check\', \'eca_nonce_check_value\' );
    $mv = get_post_meta( $post->ID, \'_ec-addons-course\', true );
    $post_type_object = get_post_type_object(\'course\');
    $name = $post_type_object->name;
    $label = $post_type_object->label;
    $posts = get_posts(
      array(
        \'post_type\'=>           \'course\',
        \'post_status\'=>         \'publish\',
        \'suppress_filters\' =>   false,
        \'posts_per_page\'=>      -1,
      )
    ); ?>

    <select name="eca-addons-course" id="eca-addons-<?php echo $name; ?>">
      <option value = "" >Tutti i <?php echo strtolower( $label ); ?></option>
    <?php foreach ( $posts as $post ) { ?>
      <option value="<?php echo $post->ID; ?>_<?php echo preg_replace(\'#[ -]+#\', \'-\' ,$post->post_title ); ?>" <?php selected( $mv, $post->ID ); ?>><?php echo $post->post_title; ?></option>
    <?php } ?>
    </select>

  <?php

  }

    public function save( $post_id )
  {

        if( !isset($_POST[\'eca_nonce_check_value\'] ) )
            return $post_id;

        $nonce = $_POST[\'eca_nonce_check_value\'];
        if( !wp_verify_nonce( \'eca_nonce_check_value\', \'eca_nonce_check\' ) )
            return $post_id;

        if (defined(\'DOING_AUTOSAVE\') && DOING_AUTOSAVE)
            return $post_id;

    $post_type = get_post_type_object( $post->post_type );

        if (!current_user_can( $post_type->cap->edit_post, $post_id ))
        return $post_id;

    $new_meta_value = ( isset( $_POST[\'ec-addons-course\'] ) ? sanitize_text_field( $_POST[\'ec-addons-course\'] ) : \'\' );
    $mk = \'ec-addons-course\';

    update_post_meta( $post->ID, $mk, $new_meta_value );
}

}

$eca_course = new eca_metabox();

add_action( \'tribe_events_single_event_after_the_content\', \'ec_addons_single_course_button_link\' );
function ec_addons_single_course_button_link()
{
  $output = "<a id =\'courseLink\' class=\'tribe-events-course-detail tribe-events-button\' href=\'#\' title=\'Vai al corso\'>Vai al dettaglio del corso </a>";
  var_dump($eca_course);

    echo \'
        <script type="text/javascript">
            jQuery(document).ready(function($){
                var course = $("\' . $output . \'");
                $(".tribe-events-cal-links").append(course);
            });
        </script>
    \';
}
在前端,th按钮显示正确,但href不起作用:现在页面重定向自身,我希望链接到我在管理元数据库下拉菜单中选择的课程的url。

谢谢你的帮助。祝你今天愉快。

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

中的代码问题eca_meta_box_function() 函数,未选择所选选项,因为option\'s值不是正在与selected() WordPress中的函数:(为清晰起见,已包装)

<option value="<?php echo $post->ID; ?>_<?php echo preg_replace(\'#[ -]+#\', \'-\' ,$post->post_title ); ?>" <!-- wrapped -->
  <?php selected( $mv, $post->ID ); ?>><?php echo $post->post_title; ?></option>
因此应:(为清晰起见,请包装)

<option value="<?php echo $post->ID; ?>" <!-- wrapped -->
  <?php selected( $mv, $post->ID ); ?>><?php echo $post->post_title; ?></option>
中的save() 函数,您应该捕获两个参数(WordPress通过save_post 挂钩)&mdash;(1)$post_id (岗位ID);和2)$post (post数据/对象),如下所示:

public function save( $post_id, $post )
也在save() 函数,您已经捕获了提交的nonce(存储在$nonce 变量),但您没有使用该变量:

wp_verify_nonce( \'eca_nonce_check_value\', \'eca_nonce_check\' )
这会阻止所选选项(或元值)保存到数据库中!因此,将其更改为:

wp_verify_nonce( $nonce, \'eca_nonce_check\' )
也在save() 函数中,您使用了错误的字段名&mdash;这个<select>eca_meta_box_function() 函数有其name 设置为eca-addons-course 如中所示<select name="eca-addons-course"...>. 然而,在save() 函数,您使用:

$_POST[\'ec-addons-course\']
当它真的应该是:

$_POST[\'eca-addons-course\']
显然,该错误还阻止了所选选项的保存!

也在save() 函数,我相信您应该使用的元键是_ec-addons-course (用于eca_meta_box_function() 功能)和非ec-addons-course:

$mk = \'ec-addons-course\';  // before; incorrect
$mk = \'_ec-addons-course\'; // after; correct
中的ec_addons_single_course_button_link() 函数,您实际上没有检索保存的元数据(以及$eca_course 无法从函数/上下文访问&mdash;你需要这样做global $eca_course; 进入该变量)。

因此,您可以像这样检索保存的元数据:

$course_ID = get_post_meta( get_the_ID(), \'_ec-addons-course\', true );
和使用get_permalink() 要检索正确的课程URL地址,请执行以下操作:

$url = esc_url( get_permalink( $course_ID ) );
更正后的代码我没有重新缩进代码(以便您可以将其与您的代码进行比较,如当前问题所示)。但是,我重命名了$mv$course_ID 因为这样更有意义。。

class eca_metabox {

    public function __construct()
  {

        add_action( \'add_meta_boxes\', array( $this, \'eca_add_meta_box\' ) );
        add_action( \'save_post\', array( $this, \'save\' ), 10, 2 );

    }

    public function eca_add_meta_box()
  {

        add_meta_box(
      \'eca-meta\',
          \'Scegli a quale corso deve linkare questo evento\',
          array(
        $this,
        \'eca_meta_box_function\'
      ),
          \'tribe_events\',
          \'normal\',
          \'high\'
    );

    }

    public function eca_meta_box_function( $post )
  {

    wp_nonce_field( \'eca_nonce_check\', \'eca_nonce_check_value\' );
    $course_ID = get_post_meta( $post->ID, \'_ec-addons-course\', true );
    $post_type_object = get_post_type_object(\'course\');
    $name = $post_type_object->name;
    $label = $post_type_object->label;
    $posts = get_posts(
      array(
        \'post_type\'=>           \'course\',
        \'post_status\'=>         \'publish\',
        \'suppress_filters\' =>   false,
        \'posts_per_page\'=>      -1,
      )
    ); ?>

    <select name="eca-addons-course" id="eca-addons-<?php echo $name; ?>">
      <option value = "" >Tutti i <?php echo strtolower( $label ); ?></option>
    <?php foreach ( $posts as $post ) { ?>
      <option value="<?php echo $post->ID; ?>" <?php selected( $course_ID, $post->ID ); ?>><?php echo $post->post_title; ?></option>
    <?php } ?>
    </select>

  <?php

  }

    public function save( $post_id, $post )
  {

        if( !isset($_POST[\'eca_nonce_check_value\'] ) )
            return $post_id;

        $nonce = $_POST[\'eca_nonce_check_value\'];
        if( !wp_verify_nonce( $nonce, \'eca_nonce_check\' ) )
            return $post_id;

        if (defined(\'DOING_AUTOSAVE\') && DOING_AUTOSAVE)
            return $post_id;

    $post_type = get_post_type_object( $post->post_type );

        if (!current_user_can( $post_type->cap->edit_post, $post_id ))
        return $post_id;

    $new_meta_value = ( isset( $_POST[\'eca-addons-course\'] ) ? sanitize_text_field( $_POST[\'eca-addons-course\'] ) : \'\' );
    $mk = \'_ec-addons-course\';

    update_post_meta( $post->ID, $mk, $new_meta_value );
}

}

$eca_course = new eca_metabox();

add_action( \'tribe_events_single_event_after_the_content\', \'ec_addons_single_course_button_link\' );
function ec_addons_single_course_button_link()
{
  $course_ID = get_post_meta( get_the_ID(), \'_ec-addons-course\', true );
  $url = esc_url( get_permalink( $course_ID ) );

  $output = "<a id=\'courseLink\' class=\'tribe-events-course-detail tribe-events-button\' href=\'$url\' title=\'Vai al corso\'>Vai al dettaglio del corso </a>";

    echo \'
        <script type="text/javascript">
            jQuery(document).ready(function($){
                var course = $("\' . $output . \'");
                $(".tribe-events-cal-links").append(course);
            });
        </script>
    \';
}

结束