入力されたデータをユーザー(投稿者)毎、年区切りで表に出力する。
データの持たせ方にも依るのかもしれないけど、今回は
- 症例とその症例に対する手術を入力
- 症例に対する手術は複数
- 手術は症例特有なものではなく、他の症例でも同じ手術がある
- それぞれの手術に加えて「その他」を追加する
- 年別に集計したデータを見たい
- ユーザー毎の集計(年別)を見たい
な感じだったので、集計用のカスタム投稿タイプとカスタムタクソノミーを「症例」「術名」と作成した。
困った?のは、管理画面は嫌だと言うことで、フロントに置いたフォームから入力してもらう事に。今回は、ACFのacf_formを使った。
症例フィールドで症例を選択すると、関連する術名を絞り込んで表示させて選択という希望だったので、悩んだ挙げ句、フィールド名とカスタムタクソノミーのターム名を関連付けて、フォームから受け取った時点でそれぞれのタクソノミーに登録することにした。
スゲー困ったのは、データの更新。
新規投稿だけなら良いんだけど、フロントからユーザー個別の投稿を編集・削除できるようにしなければならない…(^0^;)
最終的には、新規ならwp_insert_post、更新ならwp_update_postを使った。
投稿のタイトルを症例名_術名_実施日としていたので、更新時にタクソノミーを登録し直す部分で結構ハマった…。。
あとは、テーブルに出力する部分。
rowspanを設定する部分が頭ではわかってるのになかなか出せなかった。
最終的にはデータを配列に入れて、
- 症例が同じ場合はまとめる
- 術名の「その他」は並び順で一番下へ
などをunsetやらループやら使って出力した。表へ出力する場合って、配列便利なんすね
ってことで、コード。……長いんだよなぁ…。もちっと短く書けないかなぁ…( ^o^)ノ
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
function disease_data_list() { | |
echo get_disease_data_list(); | |
} | |
function get_disease_data_list() { | |
global $post; | |
$current_user = wp_get_current_user(); | |
$display_name = esc_html( $current_user->display_name ); | |
if( isset( $_GET[ 'post_id' ] ) || isset( $_GET[ 'user_id' ] ) ) { | |
$post_id = intval( $_GET[ 'post_id' ] ); | |
$user_id = intval( $_GET[ 'user_id' ] ); | |
} | |
//$year_num = ''; | |
if( isset( $_GET[ 'year_num' ] ) && ! empty( $_GET[ 'year_num' ] ) ) { | |
$year = $_GET[ 'year_num' ]; | |
} else { | |
$year = date_i18n( "Y" ); | |
} | |
?> | |
<h1 style="text-align: right;" id="post_title"><span>現在 <strong><?php echo $display_name; ?></strong> としてログイン中です。</span></h1> | |
<?php | |
if( is_user_logged_in() ) { // Display WordPress login form: | |
echo '<p class="input_logout">'; | |
wp_loginout( home_url( '/member-login' ) ); // Display "Log Out" link. | |
echo '</p>'; | |
} | |
?> | |
<h1><?php echo $year; ?>年集計</h1> | |
<div id="yealy"> | |
<?php | |
get_template_part( 'function/all_disease_by_year_list' ); | |
get_all_disease_data_list(); | |
?> | |
</div> | |
<?php | |
// 配列を準備 | |
$ope_for_soutaikan_num = 0; | |
// ユーザー一覧 | |
$args = array( | |
'role' => 'author', | |
'meta_key' => 'fetus_user_order', | |
'orderby' => 'meta_value', | |
'order' => 'ASC', | |
'count_total' => false, | |
'fields' => 'all', | |
); | |
$users = get_users( $args ); | |
foreach( $users as $user ) { | |
?> | |
<div class="hospital"> | |
<h2 class="entry-title"><?php echo esc_html( $user->display_name ); ?><span>表示</span></h2> | |
<?php | |
$args = array( | |
'post_type' => 'ope_summary', | |
'author' => $user->ID, | |
'posts_per_page' => -1, | |
); | |
$each_user_posts = get_posts( $args ); | |
$dis_names = array(); | |
$ope_name_wrap = array(); | |
$same_ope_name = array(); | |
$each_ope = array(); | |
$html = ''; | |
// tableヘッダ | |
$html .= '<div class="each_table"><table class="summary_datas each_hospital"><tbody><tr><th>症例名</th><th>術名</th><th>症例数</th></tr>'; | |
if( ! empty( $each_user_posts ) ) { | |
foreach( $each_user_posts as $post ) { | |
setup_postdata( $post ); | |
// その投稿の疾患名に対する手術名を取得し、疾患名(表示用)を取得 | |
$ope_disease = get_field( 'ope_disease', $post->ID ); | |
$ope_disease = esc_html( $ope_disease ); | |
// 手術名のカスタムフィールドkeyを作成 | |
$ope_name_key = 'ope_for_' . $ope_disease; | |
// 投稿に含まれる手術名を取得 ※ ここがカスタムタクソノミーになる!! | |
$ope_slug = get_post_meta( $post->ID, $ope_name_key, true ); | |
// 疾患名タクソノミーオブジェクト | |
$disease_term_obj = get_term_by( 'slug', $ope_disease, 'disease', OBJECT ); | |
$disease_name = esc_html( $disease_term_obj->name ); | |
$disease_count = (int)( $disease_term_obj->count ); | |
// 同名の疾患名をまとめる | |
if( ! in_array( $disease_name, $dis_names ) ) { | |
$dis_names[] = $disease_name; | |
} | |
// 手術名タクソノミーのオブジェクトをゲット | |
$ope_name_term_obj = get_term_by( 'slug', $ope_slug, 'ope_name', OBJECT ); | |
$ope_name = esc_html( $ope_name_term_obj->name ); | |
$ope_count = intval( $ope_name_term_obj->count ); | |
// 手術名タクソノミーをアップデート | |
$args = array( | |
'post_type' => 'ope_summary', | |
'posts_per_page' => -1, | |
'author' => $user->ID, | |
'tax_query' => array( | |
'relattion' => 'AND', | |
array( | |
'taxonomy' => 'disease', | |
'field' => 'slug', | |
'terms' => array( esc_html( $disease_term_obj->slug ) ), | |
), | |
array( | |
'taxonomy' => 'ope_name', | |
'field' => 'slug', | |
'terms' => array( esc_html( $ope_name_term_obj->slug ) ), | |
), | |
), | |
'meta_query' => array( | |
array( | |
'key' => 'ope_date', | |
'value' => "$year/01/01", | |
'type' => 'DATE', | |
'compare' => '>=', | |
), | |
array( | |
'key' => 'ope_date', | |
'value' => "$year/12/31", | |
'type' => 'DATE', | |
'compare' => '<=', | |
), | |
), | |
); | |
$query = get_posts( $args ); | |
$test_count = count( $query ); | |
foreach( $query as $result_post ) { | |
if( ! empty( $result_post ) ) { | |
$same_ope_name[ 'disease_name' ] = esc_html( $disease_name ); | |
$same_ope_name[ 'ope' ][ 'ope_name' ] = esc_html( $ope_name_term_obj->name ); | |
$same_ope_name[ 'ope' ][ 'test_count' ] = intval( $test_count ); | |
$ope_name_wrap[] = $same_ope_name; | |
} | |
} | |
} | |
wp_reset_postdata(); | |
$source = array_unique( $ope_name_wrap, SORT_REGULAR ); | |
$target = array(); | |
foreach ( $source as $item ) { | |
$id = $item[ 'disease_name' ]; | |
foreach ( $target as $skey=>$out ) { | |
if ( $out[ 'disease_name' ] === $id ) { | |
$outkey = $skey; | |
} | |
} | |
if ( ! isset( $outkey ) ) { | |
$each_ope[ 'ope_name' ] = $item[ 'ope' ][ 'ope_name' ]; | |
$each_ope[ 'test_count' ] = $item[ 'ope' ][ 'test_count' ]; | |
$item[ 'ope' ][] = $each_ope; | |
unset( $item[ 'ope' ][ 'ope_name' ] ); | |
unset( $item[ 'ope' ][ 'test_count' ] ); | |
$target[] = $item; | |
} else { | |
$target[ $outkey ][ 'ope' ][] = $item[ 'ope' ]; | |
unset( $outkey ); | |
} | |
} | |
// その他を最後に | |
foreach( $target as $pointer => $val ) { | |
foreach( $val[ 'ope' ] as $key => $data ) { | |
$check_string = mb_substr( $data[ 'ope_name' ], 0, 3 ); | |
if( $check_string === 'その他' ) { | |
unset( $target[ $pointer ][ 'ope' ][ $key ] ); | |
$target[ $pointer ][ 'ope' ][] = $data; | |
//array_values( $target[ $pointer ][ 'ope' ] ); | |
} | |
} | |
} | |
// テーブル作成 | |
foreach( $target as $dis_key => $ope ) { | |
// 疾患名tdのrowspan算出 | |
$rowspan_num = intval( count( $ope[ 'ope' ] ) ); | |
if( $rowspan_num >= 1 ) { | |
$html .= '<tr>'; | |
$html .= "<td class='dis_name' rowspan='" . $rowspan_num . "'>" . $ope[ 'disease_name' ] . "</td>"; | |
foreach( $ope[ 'ope' ] as $each_ope_name ) { | |
$html .= "<td class='ope_name'>" . $each_ope_name[ 'ope_name' ] . "</td>"; | |
$html .= "<td class='num'>" . $each_ope_name[ 'test_count' ] . "</td>"; | |
$html .= '</tr>'; | |
} | |
} else { | |
$html .= '<tr>'; | |
$html .= "<td class='dis_name'>" . $ope[ 'disease_name' ] . "</td>"; | |
$html .= "<td class='ope_name'>" . $ope[ 'ope' ][ 0 ][ 'ope_name' ] . "</td>"; | |
$html .= "<td class='num'>" . $ope[ 'ope' ][ 0 ][ 'test_count' ] . "</td>"; | |
$html .= '</tr>'; | |
} | |
} | |
$html .= '</tr></tbody></table></div>'; | |
echo $html; | |
} else { | |
echo "<div class='each_table'><p>まだデータはありません。</p></div>"; | |
} | |
?> | |
</div><!-- / .hospital --> | |
<?php } | |
} |