使用Foreach循环保存metabox的复选框(无效参数)

时间:2014-05-25 作者:Alessio

我是Wordpress插件开发的新手,我正在尝试创建一个复选框列表(来自WP查询),以关联为特定帖子类型的自定义字段。显示功能没有问题,但当我试图保存时,会出现错误

为foreach()提供的参数无效。

如何检查save函数在全局数组中看到的内容$loop_brands? 有人能帮我解决和理解吗?

<?php

function brands_display_meta_box( $post ) { 

    global $loop_brands;
    $loop_brands = array();

    wp_nonce_field( plugin_basename( __FILE__ ), \'brands-nonce-field\' );

    $args = array(
        \'post_type\' => \'page\',
        \'post_parent\' => 7,
        \'orderby\' => \'title\',
        \'order\' => \'ASC\'
    );

    $query_brands = new WP_Query($args);

    while ($query_brands->have_posts()) : $query_brands->the_post(); 

        $id_brand = get_the_ID();
        $brand = get_post($id_brand, ARRAY_A);
        $slug_brand = $brand[\'post_name\'];
        $titolo_brand = $brand[\'post_title\'];

        $loop_brands[] = $slug_brand;

?>

        <p>
            <input type="checkbox" id="<?php echo $slug_brand; ?>" name="<?php echo $slug_brand; ?>" value="yes" <?php checked( get_post_meta($post->ID, $slug_brand, true ), \'yes\' ); ?>>
            <label for="<?php echo $slug_brand; ?>"><?php echo $titolo_brand; ?></label>

        </p>

<?php endwhile;

}

function brands_add_meta_box() {

    add_meta_box(
        \'brands-meta-box\',
        \'brands Meta Box\',
        \'brands_display_meta_box\',
        \'stores\',
        \'side\',
        \'high\'
    );

}

add_action( \'add_meta_boxes\', \'brands_add_meta_box\' );

function brands_user_can_save( $post_id, $nonce ) {

    $is_autosave = wp_is_post_autosave( $post_id );
    $is_revision = wp_is_post_revision( $post_id );
    $is_valid_nonce = ( isset( $_POST[ $nonce ] ) && wp_verify_nonce( $_POST[ $nonce ], plugin_basename( __FILE__ ) ) );

    return ! ( $is_autosave || $is_revision ) && $is_valid_nonce;

}

function brands_save_meta_box( $post_id ) {

    global $loop_brands;

    foreach ( $loop_brands as $brand ) {

        if ( brands_user_can_save( $post_id, $brand ) ) {

            if ( isset( $_POST[ $brand ] ) ) {

                update_post_meta( $post_id, $brand, $_POST[ $brand ]);

            } else {

                delete_post_meta( $post_id, $brand);

            }

        }

    }

}

add_action( \'save_post\', \'brands_save_meta_box\');

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

我的建议是提取代码的查询部分:

function get_brands() {
  $loop_brands = array();

  wp_nonce_field( plugin_basename( __FILE__ ), \'brands-nonce-field\' );

  $args = array(
      \'post_type\' => \'page\',
      \'post_parent\' => 7,
      \'orderby\' => \'title\',
      \'order\' => \'ASC\'
  );

  $query_brands = new WP_Query($args);
  return $query_brands;
}
然后像这样使用:

function brands_save_meta_box( $post_id ) {
    $loop_brands = get_brands();
    $loop_brands = wp_list_pluck($loop_brands->posts,\'post_name\');
    foreach ( $loop_brands as $brand ) {
        if ( brands_user_can_save( $post_id, $brand ) ) {
            if ( isset( $_POST[ $brand ] ) ) {
                update_post_meta( $post_id, $brand, $_POST[ $brand ]);
            } else {
                delete_post_meta( $post_id, $brand);
            }
        }
    }
}
这将是第一步。除非我犯了错误,否则代码应该像以前一样工作,但不必担心global.

然后,如果愿意,您可以转向更复杂的解决方案,该解决方案涉及一些“缓存”:

function brands_query() {
  $loop_brands = array();

  wp_nonce_field( plugin_basename( __FILE__ ), \'brands-nonce-field\' );

  $args = array(
      \'post_type\' => \'page\',
      \'post_parent\' => 7,
      \'orderby\' => \'title\',
      \'order\' => \'ASC\'
  );

  $query_brands = new WP_Query($args);
  return $query_brands;
}

function get_brands() {
  $brands = get_option(\'loop_brands\');
  if (empty($brands)) {
    $brands = brands_query();
    update_option(\'loop_brands\',$brands);
  }
  return $brands;
}
如果我读对了,你真的只需要刷新一下loop_brands 在页面上保存。类似这样:

function save_brands($post_id) {
  $brands = brands_query();
  update_option(\'loop_brands\',$brands);
}
add_action(\'save_post_page\',\'save_brands\');

SO网友:helgatheviking

基本上$loop_brands 未转入保存功能。所以你在跑步foreach 在空/假变量上,则会出现错误。我建议保存$loop_brands 作为一种过渡或选择。在这里,我尝试了一个过渡。我认为您不需要一种清除瞬态的方法,因为每次加载metabox时,瞬态都会被刷新,因此在保存例程运行时,瞬态应该是最新的。我还没有测试过这个,所以你的里程数可能会有所不同。

function brands_display_meta_box( $post ) { 

    wp_nonce_field( plugin_basename( __FILE__ ), \'brands-nonce-field\' );

    $args = array(
        \'post_type\' => \'page\',
        \'post_parent\' => 7,
        \'orderby\' => \'title\',
        \'order\' => \'ASC\'
    );

    $query_brands = new WP_Query($args);

    while ($query_brands->have_posts()) : $query_brands->the_post(); 

        $id_brand = get_the_ID();
        $brand = get_post($id_brand, ARRAY_A);
        $slug_brand = $brand[\'post_name\'];
        $titolo_brand = $brand[\'post_title\'];

        $loop_brands[] = $slug_brand;

?>

        <p>
            <input type="checkbox" id="<?php echo $slug_brand; ?>" name="<?php echo $slug_brand; ?>" value="yes" <?php checked( get_post_meta($post->ID, $slug_brand, true ), \'yes\' ); ?>>
            <label for="<?php echo $slug_brand; ?>"><?php echo $titolo_brand; ?></label>

        </p>

<?php endwhile;

    set_transient( \'loop_brands\', $loop_brands );

}

function brands_add_meta_box() {

    add_meta_box(
        \'brands-meta-box\',
        \'brands Meta Box\',
        \'brands_display_meta_box\',
        \'stores\',
        \'side\',
        \'high\'
    );

}

add_action( \'add_meta_boxes\', \'brands_add_meta_box\' );

function brands_user_can_save( $post_id, $nonce ) {

    $is_autosave = wp_is_post_autosave( $post_id );
    $is_revision = wp_is_post_revision( $post_id );
    $is_valid_nonce = ( isset( $_POST[ $nonce ] ) && wp_verify_nonce( $_POST[ $nonce ], plugin_basename( __FILE__ ) ) );

    return ! ( $is_autosave || $is_revision ) && $is_valid_nonce;

}

function brands_save_meta_box( $post_id ) {

    $loop_brands = get_transient( \'loop_brands\' );

    if( $loop_brands ):

    foreach ( $loop_brands as $brand ) {

        if ( brands_user_can_save( $post_id, $brand ) ) {

            if ( isset( $_POST[ $brand ] ) ) {

                update_post_meta( $post_id, $brand, $_POST[ $brand ]);

            } else {

                delete_post_meta( $post_id, $brand);

            }

        }

    }
    endif;

}

add_action( \'save_post\', \'brands_save_meta_box\');

结束

相关推荐

Editing wp-includes/feed.php

我不明白为什么我的RSS没有更新,在经历了很多哀嚎和咬牙切齿之后,我相信我已经通过编辑wp includes/feed在一定程度上解决了这个问题。php。我更改了以下内容:$feed->set_cache_duration( apply_filters( \'wp_feed_cache_transient_lifetime\', 12 * HOUR_IN_SECONDS, $url ) ); 对此:$feed->set_cache_duration( apply_filters( \