web-dev-qa-db-ja.com

メタボックスのチェックボックスをforeachループで保存する(無効な数)

私はWordpressのプラグイン開発に不慣れで、特定の投稿タイプのカスタムフィールドとして関連付けるチェックボックスのリストを(WP Queryから)作成しようとしています。表示機能に問題はありませんが、保存しようとするとエラーになります。

Foreach()に無効な引数が指定されました。

グローバル配列$loop_brandsでsave関数が何を見ているのかを確認するにはどうすればいいですか?誰かが私が解決し、理解するのを手伝うことができますか?

<?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');
1
Alessio

私のアドバイスはあなたのコードのクエリ部分を抽出することでしょう:

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');
1
s_ha_dum

基本的に、あなたの$loop_brandsはsave関数に引き継がれません。だからあなたは空/偽の変数でforeachを実行しているので、エラーになります。 $loop_brandsを一時的またはオプションとして保存することをお勧めします。ここで私はトランジェントを試しました。メタボックスがロードされるたびにトランジェントが更新されるので、トランジェントをクリアする方法は必要ないと思います。したがって、保存ルーチンが実行されるときにはトランジェントを最新の状態にする必要があります。私はこれをテストしていないので、あなたの走行距離は変わるかもしれません。

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');
1
helgatheviking