私は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');
私のアドバイスはあなたのコードのクエリ部分を抽出することでしょう:
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');
基本的に、あなたの$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');