特殊な例なので参考になる人は少ないと思いますがメモ。
管理画面のカスタム投稿タイプ一覧に「Advanced Custom Fields」プラグインで作成したカスタムフィールド(日付:デイトピッカー)を表示。
更にその日付順で並べる、という作業を行いました。
問題無く反映されたと思いきや、サイト更新時に不具合が発生したので解決方法の記録です。
カスタムフィールドの項目を管理画面のカスタム投稿タイプの一覧に表示
※下記プロジェクトは簡易化したサンプルです。実際は複数のカスタムフィールドの列を追加しています。
カスタム投稿タイプ「イベント(event)」の一覧に、カスタムフィールド「年月日(event_date)」の列を表示する必要がありました。
まずは列を追加して
[php]
//『event』カスタム投稿にカスタムフィールド『event_date』の項目を追加
function add_column_to_event ( $columns ) {
$columns[‘event_date’] = "年月日";
return $columns;
}
add_filter( ‘manage_event_posts_columns’, ‘add_column_to_event’ );
</code>
[/php]
追加した項目に値(日付データ)を入れます。
[php]
//追加したカスタムフィールドの項目に値を表示
function add_column_value_to_event ($column, $post_id) {
switch ( $column ) {
case ‘event_date’ :
echo get_post_meta( $post_id , ‘event_date’ , true );
break;
}
}
add_filter( ‘manage_event_posts_custom_column’, ‘add_column_value_to_event’, 10, 2 );
[/php]
そして、カスタムフィールドで追加した日付順(降順)で並べます。下のような感じのコードになります。
[php]
//カスタム投稿『event』一覧を、カスタムフィールド『event_date』の降順で並べ替え
function set_post_types_admin_order_to_event ( $wp_query ) {
if (is_admin()) {
$post_type = $wp_query->query[‘post_type’];
if ( $post_type == ‘event’ ) {
$wp_query->set(‘meta_key’, ‘event_date’);
$wp_query->set(‘orderby’, ‘meta_value’);
$wp_query->set(‘order’, ‘DSC’);
}
}
}
add_filter( ‘pre_get_posts’, ‘set_post_types_admin_order_to_event’ );
[/php]
問題無く表示されました。
更新すると問題発生。日付形式が強制的に上書きされる
しかし、過去のデータを編集し、保存しなおしたところ問題が発生しました。
例えばカスタムフィールドで登録した日付「2018/09/01」の記事を修正、保存すると、日付は変更していないのにも関わらず、一覧では「20180901」と表示され、順番が狂ってしまうのです。
つまり、保存時に日付のフォーマットが強制的に書き換えられているということです。
原因。プラグインのアップデートによる仕様変更によるもの
そこで、Advanced Custom Fields公式ドキュメントの「Date Picker」を確認してみます。
https://www.advancedcustomfields.com/resources/date-picker/
冒頭から理由が記載されていました。
要約すると次のような感じです。
ACF(アドバンスドカスタムフィールド)の以前のバージョンには「保存形式(Save Format)」という設定が含まれていました。
この設定により、開発者はDBに保存されている形式を変更できました。
保存形式の指定は便利ではありますが、多くの問題を引き起こす為、新バージョンでは削除されました。
現在は「YYYYMMDD」を唯一の保存フォーマットとしています。
公式サイトより一部意訳
つまり、データベースには「2018/09/01」のフォーマットで保存されていても、新バージョンでは「20180901」で保存されるということです。
データベースをチェックしてみる
念の為phpMyAdminでデータベースを確認してみます。
カスタムフィールドのキーと値はpost_metaテーブルに入っています。
該当のカスタムフィールドで検索してみます。
有りました。更新済の記事のみ基本フォーマットで保存されています。一覧表示での順序の崩れの原因が確定しました。
旧バージョン(5以前)を確認
試しにプラグインダウンロードページで、旧バージョンのACFをダウンロード、確認してみます。適当にバージョン4.3.8をインストールしてみます。
なるほど、「フォーマットを保存する」の項目があります。覚えていませんが、恐らく以前ここでフォーマットを指定していたと思われます。
ちなみに最新バージョンは下記のような画面です。
※「Translation preferences」はマルチ言語プラグイン「WPML」によるもので、今回は無関係です。
修正する
「じゃあ全部新しい形式にする為に記事を保存し直せばよいか」と言いたいところですが、このカスタム投稿タイプには1500程度の記事が登録されていました。
元々、これらの記事はCSVから「Really Simple CSV Importer」を使って一気に読み込んだものです。
CSVを確認したところ、確かに「2018/09/01」形式(Y/m/d)で日付を記入しています。ソフトはLibreOfficeを使っています。
何らかの方法で記事をCSVに書き出し、日付を一気に修正、読み込み直す、という方法は記事IDの保持が面倒そうなので、データベースを書き換えることにしました。
データベースで日付を置換
phpMyAdminにログイン後、SQLタブを開きます。
「wp_postmeta」というテーブルの「event_date」キーにあるデータから、「/」を取り除きたい。つまり「2018/09/01」を「20180901」にしたい、というSQLクエリは下のように書きます。
[sql][/sql]update wp_postmeta set meta_value=REPLACE(`meta_value`,’/’,”) where meta_key = ‘event_date’;[sql][/sql]
無事に全て置換されました。
管理画面でもカスタムフィールドで指定した日付の降順で並んでいます。
日付の表示を修正
管理画面とはいえ、この日付フォーマットは少々味気ないのでY/m/d形式で表示することにします。
値を表示するコードを下記のように修正します。
[php]
//追加したカスタムフィールドの項目に値を表示。日付フォーマットも変更。
function add_column_value_to_event ($column, $post_id) {
switch ( $column ) {
case ‘event_date’ :
$date = get_post_meta( $post_id , ‘event_date’ , true );
$date = new DateTime($date);
echo $date->format(‘Y/m/d’);
break;
}
}
add_filter( ‘manage_event_posts_custom_column’, ‘add_column_value_to_event’, 10, 2 );
[/php]
表示形式が修正されました。