WordPressのWp-Queryでカスタムフィールドの値を取得して、変数にその配列を格納し、ループ外でarray_sum()を使って合計を再び変数に格納して、別の足し算などの計算もしながらHTMLで表示させます。
この記事の内容はPHP56で動作します。PHP70以降では正常に動作しません。
ページ内リンク
実際のサイトでの使い方解説
サッカーリーグのサイトで、試合結果の投稿ページのカスタムフィールドに対戦チームや得点や勝点等の試合結果情報を全て入力しただけで、年間ランキング等の別ページにその内容を表示させる為のコードの解説です。
WordPressのWP-Queryでカスタムフィールドの値の配列を変数に格納してfor文で記事情報取得を繰り返しjQueryで順位付け。
の追加の解説になり、そのページのコードの中にある86行目の「nenkan-team-rank-query.php」ファイルの内容になります。
カスタム投稿ページの「team」から登録チーム数だけ「nenkan-team-rank-query.php」の内容の繰り返し処理が行われます。
実際のコード
「nenkan-team-rank-query.php」の内容です。
/***team_aでkachiten-aに3がある勝の時***/ <?php $hweb_query = new WP_Query( array( 'cat'=>34, 'order'=>'ASC', 'posts_per_page' => 12, 'orderby'=>'meta_value', 'meta_key'=>'wpcf-date', 'meta_query' => array( array( 'key'=>'wpcf-team_a', 'value'=>$team_name2_query, 'compare'=>'=' ), array( 'key'=>'wpcf-kachiten_a', 'value'=>'3', 'compare'=>'=' ), array( 'key'=>'wpcf-nen', 'value'=>get_post_meta(get_the_ID() , 'wpcf-nen' ,true), 'compare'=>'=' ), 'relation'=>'AND' ), ) ); ?> <?php if ( $hweb_query->have_posts() ) : ?> <?php while ( $hweb_query->have_posts() ) : $hweb_query->the_post();?> <?php $kachi_suu++ ;?> <?php $kachiten_a[] = post_custom('wpcf-kachiten_a'); ?> <?php $tokuten_a[] = post_custom('wpcf-tokuten_a'); ?> <?php $shitten_a[] = post_custom('wpcf-tokuten_b'); ?> <?php endwhile;?> <?php wp_reset_postdata();?> <?php else : ?> <?php $kachi_suu=0;?> <?php $kachiten_a=0;?> <?php $tokuten_a=0;?> <?php $shitten_a=0;?> <?php endif;?> /******team_aでkachiten_aに1がある引分の時*********/ <?php $hweb_query = new WP_Query( array( 'cat'=>34, 'order'=>'ASC', 'posts_per_page' => 12, 'orderby'=>'meta_value', 'meta_key'=>'wpcf-date', 'meta_query' => array( array( 'key'=>'wpcf-team_a', 'value'=>$team_name2_query, 'compare'=>'=' ), array( 'key'=>'wpcf-kachiten_a', 'value'=>'1', 'compare'=>'=' ), array( 'key'=>'wpcf-nen', 'value'=>get_post_meta(get_the_ID() , 'wpcf-nen' ,true), 'compare'=>'=' ), 'relation'=>'AND' ), ) ); ?> <?php if ( $hweb_query->have_posts() ) : ?> <?php while ( $hweb_query->have_posts() ) : $hweb_query->the_post();?> <?php $wake_suu_a++ ;?> <?php $kachiten_a_wake[] = post_custom('wpcf-kachiten_a'); ?> <?php $tokuten_a_wake[] = post_custom('wpcf-tokuten_a'); ?> <?php $shitten_a_wake[] = post_custom('wpcf-tokuten_b'); ?> <?php endwhile;?> <?php wp_reset_postdata();?> <?php else : ?> <?php $wake_suu_a=0;?> <?php $kachiten_a_wake=0;?> <?php $tokuten_a_wake=0;?> <?php $shitten_a_wake=0;?> <?php endif;?> /******team-bでkachiten_bに1がある引分の時*********/ <?php $hweb_query = new WP_Query( array( 'cat'=>34, 'order'=>'ASC', 'posts_per_page' => 12, 'orderby'=>'meta_value', 'meta_key'=>'wpcf-date', 'meta_query' => array( array( 'key'=>'wpcf-team_b', 'value'=>$team_name2_query, 'compare'=>'=' ), array( 'key'=>'wpcf-kachiten_b', 'value'=>'1', 'compare'=>'=' ), array( 'key'=>'wpcf-nen', 'value'=>get_post_meta(get_the_ID() , 'wpcf-nen' ,true), 'compare'=>'=' ), 'relation'=>'AND' ), ) ); ?> <?php if ( $hweb_query->have_posts() ) : ?> <?php while ( $hweb_query->have_posts() ) : $hweb_query->the_post();?> <?php $wake_suu_b++ ;?> <?php $kachiten_b_wake[] = post_custom('wpcf-kachiten_b'); ?> <?php $tokuten_b_wake[] = post_custom('wpcf-tokuten_b'); ?> <?php $shitten_b_wake[] = post_custom('wpcf-tokuten_a'); ?> <?php endwhile;?> <?php wp_reset_postdata();?> <?php else : ?> <?php $wake_suu_b=0;?> <?php $kachiten_b_wake=0;?> <?php $tokuten_b_wake=0;?> <?php $shitten_b_wake=0;?> <?php endif;?> <?php $wake_suu = $wake_suu_a + $wake_suu_b ;?> <?php $kachiten_goukei=array_sum($kachiten_a)+array_sum($kachiten_a_wake)+array_sum($kachiten_b_wake);?> /****team_bでkachiten_aに3の負けの時kachiten_bに0を入力しているが0は無と判断される場合がある****/ <?php $hweb_query = new WP_Query( array( 'cat'=>34, 'order'=>'ASC', 'posts_per_page' => 12, 'orderby'=>'meta_value', 'meta_key'=>'wpcf-date', 'meta_query' => array( array( 'key'=>'wpcf-team_b', 'value'=>$team_name2_query, 'compare'=>'=' ), array( 'key'=>'wpcf-kachiten_a', 'value'=>'3', 'compare'=>'=' ), array( 'key'=>'wpcf-nen', 'value'=>get_post_meta(get_the_ID() , 'wpcf-nen' ,true), 'compare'=>'=' ), 'relation'=>'AND' ), ) ); ?> <?php if ( $hweb_query->have_posts() ) : ?> <?php while ( $hweb_query->have_posts() ) : $hweb_query->the_post();?> <?php $make_suu ++ ;?> <?php $tokuten_make[] = post_custom('wpcf-tokuten_b'); ?> <?php $shitten_make[] = post_custom('wpcf-tokuten_a'); ?> <?php endwhile;?> <?php wp_reset_postdata();?> <?php else : ?> <?php $make_suu=0;?> <?php $tokuten_make=0;?> <?php $shitten_make=0;?> <?php endif;?> /*****************************/ <?php $tokuten_goukei=array_sum($tokuten_a)+array_sum($tokuten_a_wake)+array_sum($tokuten_b_wake)+array_sum($tokuten_make);?> <?php $shitten_goukei=array_sum($shitten_a)+array_sum($shitten_a_wake)+array_sum($shitten_b_wake)+array_sum($shitten_make);?> <?php $shiai_suu = $make_suu + $wake_suu + $kachi_suu ;?> <?php $toku_shitten_sa=$tokuten_goukei-$shitten_goukei;?> /****チームランキング表の<tr>部分でここが繰り返し表示される****/ <tr id="<?php echo $kachiten_goukei_plus250 = 250 + $kachiten_goukei;?><?php echo $shiai_suu_plus250 = 250 + $shiai_suu ;?><?php echo $toku_shitten_sa_plus250 = 250 + $toku_shitten_sa;?><?php echo $toukou_nichi[$i];?>"> <td class="juni"></td> <td class="team-name yuni-<?php echo $team_name2_query ;?><?php echo $yunihoum[$i] ;?>"><a href="<?php echo home_url() ?>/<?php echo $team_name2_query ;?>/" title="<?php echo $team_name[$i] ;?>ホームページへ"><?php echo $team_name[$i] ;?></a></td> <td class="league"><?php echo $team_rank[$i] ;?></td> <td class="champ"><?php echo $yusho_suu[$i] ;?></td> <td class="shiaisuu"><?php echo $shiai_suu ;?></td> <td class="katiten"><?php echo $kachiten_goukei;?></td> <td class="kati"><?php echo $kachi_suu ;?></td> <td class="wake"><?php echo $wake_suu ;?></td> <td class="make"><?php echo $make_suu ;?></td> <td class="ten"><?php echo $tokuten_goukei;?></td> <td class="shitten"><?php echo $shitten_goukei;?></td> <td class="tensa"><?php echo $toku_shitten_sa;?></td> </tr>
実際のサイトでのコードの役割と概要
このコードは201行目までの4つのWp-Queryで情報を取得しています。
1つ目のWP-Queryはteam_aに入力されいるチームが勝った場合、2つ目はteam_aに入力されいるチームが引分けた場合、3つ目はteam_bに入力されいるチームが引分けた場合、4つ目はteam_bに入力されいるチームが負けた場合です。
このサッカーリーグの試合結果ページでは勝ったチームがteam_aに入力され、負けたチームがteam_bに入力され、引分けた場合は成績上位チームがteam_aに入力されます。
この4つで各チームの全ての試合結果の情報が取得できます。
153行目や205行目からの「array_sum()」は、取得したカスタムフィールドの値の配列を合計しています。
151・208・210行目で4つのWp-Queryで取得した各々の記事数を変数に格納して、ループ外で計算しています。
214行目からはここまでで取得して変数に格納した値を、HTMLの「<tr>」の要素に充てはめていって、各登録チームのランキングの勝点、勝数、引分数、負数、得点等を表示させます。
WP-Queryのパラメータ
4つのWP-Queryのパラメーターは「‘meta_query’」の内容を除き共通しています。
「‘cat’=>34,’order’=>’ASC’,’posts_per_page’ => 12,’orderby’=>’meta_value’,’meta_key’=>’wpcf-date’,」
はカテゴリーIDが34(このサイトの場合「試合結果」)の投稿を12件、カスタムフィールドの名前「‘wpcf-date’」(試合日)の値の昇順で取得するという事です。
3つのmeta_query
パラメーターの「meta_query」では3つの条件に合致したものを取得する内容になっています。
1つ目はチーム名
1つ目の条件14-16行目の
「‘key’=>’wpcf-team_a’,’value’=>$team_name2_query,’compare’=>’=’」
はカテゴリーID34「試合結果」の投稿ページのカスタムフィールドの「wpcf-team_a」と、変数「$team_name2_query」に格納されている値が、「‘compare’=>’=’」同じ場合という事です。
変数「$team_name2_query」に格納されているのは
WordPressのWP-Queryでカスタムフィールドの値の配列を変数に格納してfor文で記事情報取得を繰り返しjQueryで順位付け。
のコードの21行目で取得し、56行目で変数に格納している値です。
2つ目は試合結果の勝敗
2つ目の条件19-21行目の
「‘key’=>’wpcf-kachiten_a’,’value’=>’3′,’compare’=>’=’」
は試合の勝点を「wpcf-kachiten_a」に入力していて、その値が3「‘value’=>’3’」と同じ場合という事です。
ご存知の通りサッカーの試合では勝った場合は勝点3、引分は1、負けは0です。
3つ目は試合の年
3つ目の条件24-26行目の
「‘key’=>’wpcf-nen’,’value’=>get_post_meta(get_the_ID() , ‘wpcf-nen’ ,true),’compare’=>’=’」
は何年の試合結果を取得してくるかという事です。
「‘value’=>get_post_meta(get_the_ID() , ‘wpcf-nen’ ,true)」は年間ランキングの投稿ページのカスタムフィールドの「wpcf-nen」に入力されている値です。
例えば2017年間ランキングの投稿ページの場合は「2017」が入力されています。
各試合結果の投稿ページにも試合が行われた年月日が同じカスタムフィールドで入力されています。
3つのmeta_queryの条件一致
「‘relation’=>’AND’」は3つのmeta_queryの条件一致した記事という事です。
「‘relation’」には「‘AND’」か「‘OR’」を指定できます。
取得したカスタムフィールドの値を変数に格納
記事数格納
37行目の「$kachi_suu++」は3つのmeta_queryを含むWP-Queryのパラメーターの条件で取得した記事の記事数を取得して変数「$kachi_suu」に格納しています。
値の配列を格納
38-40行目は「team_a」の「wpcf-kachiten_a」(勝点)と「wpcf-tokuten_a」(得点)と「wpcf-tokuten_b」(失点)の値の配列を各変数に格納しています。
「wpcf-tokuten_b」(失点)は「team_a」の試合時の「team_b」の得点になるので「team_a」にとっては失点になります。
条件に合致する記事がなかった場合
条件に合致する記事がなかった場合、つまり44行目の「else」ですが、その場合は0を変数に格納します。
後で足し算を行うので0を入力した方が確実だと判断しました。
引分の場合の2つのWP-Query
53-153行目までは引分の場合の2つのWP-Queryです。
引分の場合は勝点が1なので70行目と120行目は「‘value’=>’1’」となります。
2つWP-Queryがあるのは引分の場合はチーム名が「wpcf-team_a」と「wpcf-team_b」に入力されている場合があるからです。
引分2つのWP-Queryで取得した値を格納した記事数の変数を151行目で「$wake_suu = $wake_suu_a + $wake_suu_b」足し算して「wpcf-team_a」と「wpcf-team_b」に入力されている場合の合計を変数「$wake_suu」に格納しています。
勝点の合計
ここまでの、勝った場合のWP-Query、引分けた場合2つのWP-Queryで取得した勝点を153行目
「$kachiten_goukei=array_sum($kachiten_a)+array_sum($kachiten_a_wake)+array_sum($kachiten_b_wake)」
で足し算して合計して「$kachiten_goukei」格納しています。
配列の合計を出すarray_sum()
「array_sum()」は配列の値の数値を合計します。
「array_sum($kachiten_a)」の場合「$kachiten_a」に格納されている数値の配列を合計しています。
最後4つ目のWP-Queryで負けを取得
157-201行目で負けた場合の得点や失点を取得しています。
負けた場合勝点0なので勝ち点の取得は必要ありません。
負けた場合勝点を入力する欄に0と入力するわけですが、0の値を取得しようとするとうまくいかない場合があると判断したので、168行目で「‘key’=>’wpcf-team_b’」にチーム名が入力されている場合となっているのですが、173-174行目で「‘key’=>’wpcf-kachiten_a’,’value’=>’3′,」としています。
HTMLの表の<tr>に各変数を設定
205-210行目までは得点、失点、試合数、得失点差を計算して、ランキングに必要なデータは全て揃いました。
ここまでの全てのデータをHTMLの表の<tr>に214-227行目で各変数や変数の計算を設定していきます。
順位の規則
順位は勝点、試合数、得失点差、勝数、得点、前年度ランキング順位の順で決定しています。
この中で勝点、試合数、得失点差までは自動で順位付けして、それでも同じの場合は登録チームの投稿日を手動で調整する事にしました。
jQueryでの順位付けのidとその桁数
214行目は「<tr>」にjQueryで順位付けする為、CSSのidに勝点、試合数、得失点差に250を加算した数値を自動付加させています。
「$kachiten_goukei_plus250 = 250 + $kachiten_goukei」等各データに250を足しています。
これはチームによって勝点や得点が2桁だったり、1桁だったり、得失点差がマイナスだったりしても、250を足す事で同じ桁数にして、jQueryで比較出来るようにする為です。
具体的には例えば勝点15、試合数8、得失点差12のチームAと勝点3、試合数6、得失点差-5のチームBがあったとします。
この場合、214行目のコードで表示するとチームAは「<tr id=”265258262″>」となり、チームBは「<tr id=”253256245″>」となり、チームAの方がidの数値が大きくなりjQueryで上位に表示できます。
jQueryでHTMLの要素を並べ替えて順位付けする
で詳しく解説しています。
+250の理由
jQueryで順位付けする為には250でなければならないというわけではありません。
300でも400でも500でも、桁数がかわらなければ問題ありません。
勝点や試合数や得失点差をそのまま表示させるとチームAは「15812」となり、チームBは「36-5」となってしまい、桁数が合わなかったり、数値にならなかったりで、jQueryで比較する事が出来なくなるからです。
+250にしておけば、得失点差が+749以下で、-149までならjQueryで比較する数値の桁数が違ってしまう事はありません。
[$i]の解説
214行目の最後の「echo $toukou_nichi[$i]」の「[$i]」は
WordPressのWP-Queryでカスタムフィールドの値の配列を変数に格納してfor文で記事情報取得を繰り返しjQueryで順位付け。
のコードの20-26行目で変数に格納している要素の、53-56行目for文で繰り返している配列の番号です。
1年間13試合目からは
このサッカーリーグでは登録チームが毎月1試合、1年間で12試合行っています。
チームによって月2試合したい場合は2チーム登録もできます。
年間12試合を越えたらパラメーターで13試合目の記事から情報を取得して、記事数が1より上の場合trを表示させればチーム名Bとしてランキング表に表示できます。