質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
WordPress

WordPressは、PHPで開発されているオープンソースのブログソフトウェアです。データベース管理システムにはMySQLを用いています。フリーのブログソフトウェアの中では最も人気が高く、PHPとHTMLを使って簡単にテンプレートをカスタマイズすることができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

2回答

5515閲覧

[WordPress] Advanced Custom Fieldsでget_field使用時に上手く値が取れない

Yashichi

総合スコア35

WordPress

WordPressは、PHPで開発されているオープンソースのブログソフトウェアです。データベース管理システムにはMySQLを用いています。フリーのブログソフトウェアの中では最も人気が高く、PHPとHTMLを使って簡単にテンプレートをカスタマイズすることができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2018/01/07 19:48

編集2018/01/08 05:54

###追記2
DB未保存のカスタムフィールドの値を取得するのに、
$_POST["fields"]["フィールドキー"](フィールドキーは$_POST["fields"]をvar_dumpすると取れます)を使うことが分かりました。これを使えば投稿の新規作成時でもカスタムフィールドの値が取れます。

しかし、これを使うと、下記のように全ての値が
新規作成時の投稿のカスタムフィールドのものと同じになってしまいます。

array(2) { ["field_5a50f527cbddc"]=> string(3) "yes" ["field_5a52618c69f7f"]=> string(0) "" } array(2) { ["field_5a50f527cbddc"]=> string(3) "yes" ["field_5a52618c69f7f"]=> string(0) "" } array(2) { ["field_5a50f527cbddc"]=> string(3) "yes" ["field_5a52618c69f7f"]=> string(0) "" } array(2) { ["field_5a50f527cbddc"]=> string(3) "yes" ["field_5a52618c69f7f"]=> string(0) "" } array(2) { ["field_5a50f527cbddc"]=> string(3) "yes" ["field_5a52618c69f7f"]=> string(0) "" }

###追記
mizさんに教えていただきましたこちらのページ(そのページに載ってたリンクも含む)を見て、
カスタムフィールドの値を取得するタイミングとアクションを起こすタイミングが上手くいっていないということまでは分かりました。
(そこからが分かりません..)
■ACF | acf/save_post
https://www.advancedcustomfields.com/resources/acf-save_post/
■Why isn't acf/save_post firing? - ACF Support
https://support.advancedcustomfields.com/forums/topic/why-isnt-acfsave_post-firing/
###前提・実現したいこと
WordPressで投稿を新規作成したタイミング(投稿を更新したりしたタイミングも含む)で、
その投稿のタイトルや投稿時間をJSONファイルに突っ込むという実装をおこなっています。

投稿の新規作成時に
その内容にACFで作成したラジオボタンの値も含めたいというのが実現したいことです。

###発生している問題・エラーメッセージ
投稿を新規作成したタイミングだと、ラジオボタンの値が反映されません。
しかし、投稿を更新したりすると値が反映されるようになります。

######JSONの値(正しい形)

{ "title":"test", "start":"2018-01-08 03:53:31", "url":"http:test.jp/static_directory/archive/123", "value":ok }

値の一番下"value"にACFのget_fieldで取得した値が入ります。
ラジオボタンにはokとnoを設定しているのでそのどちらかが入るはずです。

######JSONの値(現状)

{ "title":"test", "start":"2018-01-08 03:53:31", "url":"http:test.jp/static_directory/archive/123", "value":false }

現状はfalseになっています。

###該当のソースコード

PHP

1<?php 2 3/** 4 * 投稿が行なわれたタイミングでJSONファイルを生成するフック 5 * 6 * @param string $new_status 新しいステータス 7 * @param string $old_status 以前のステータス 8 * @param object $post 該当する投稿オブジェクト 9 */ 10function makes_json($new_status, $old_status, $post) { 11 12 13if (function_exists('xdebug_disable')) { 14 xdebug_disable(); 15} 16 17 if($new_status == 'publish') { 18 switch($old_status) { 19 case 'draft': 20 case 'pending': 21 case 'auto-draft': 22 case 'future': 23 case 'publish': 24 case 'inherit': 25 // Get ALL Posts 26 $args = array( 27 'numberposts' => -1, 28 'orderby' => 'post_date', 29 'order' => 'DESC', 30 ); 31 $posts = get_posts($args); 32 $homeUrl = 'http:test.jp/static_directory'; 33 if (count($posts) == 0) { return; } 34 foreach ($posts as $post) { 35 $cal_fields = get_field("switch", $post->ID); 36 $output_json[date('Ym', strtotime($post->post_date))][] = array( 37 'title' => $post->post_title, 38 'start' => $post->post_date, 39 'url' => $homeUrl . '/archives/' . $post->ID, 40 'value' => $cal_fields, 41 ); 42 } 43 44 // Get Upload Directory 45 $upload_dir = wp_upload_dir(); 46 $upload_dir = $upload_dir['basedir'].'/json'; 47 48 // Create Directory 49 if (file_exists($upload_dir) == FALSE) { 50 mkdir($upload_dir, 0777); 51 } 52 53 // Delete All JSON Files 54 array_map('unlink', glob($upload_dir.'/*.json')); 55 56 // Create JSON Files 57 foreach ($output_json as $key => $value) { 58 file_put_contents($upload_dir . '/'.$key.'.json', json_encode($value)); 59 } 60 break; 61 } 62 } 63} 64add_action('transition_post_status', 'makes_json', 10, 3); 65

###試したこと
この自作関数内のコードの一部分(file_put_contentsなどファイルやディレクトリの作成を除く)を投稿一覧ページのPHPファイルに移してみると、
投稿の新規作成時の段階で、ラジオボタンの値をちゃんと取ることができました。

デバッグとして、get_field()でラジオボタンの値を取得するタイミングをズラすために
sleep()を指定しましたが、効果はありませんでした。

その他var_dump()を使って投稿一覧ページでテストしたときの
$postの値と比較をしたりしましたが、
比較して異なる大きな部分としては、get_field()が、
投稿の新規作成時に働くか否かという部分でした。

###補足情報(言語/FW/ツール等のバージョンなど)
PHP 7.1.9
WordPress 4.9

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Yashichi

2018/01/08 04:02 編集

@miz さん ありがとうございます。このページによれば、"transition_post_status"を使うのは良いけど、投稿新規作成時の投稿取得の方法が通常のget_fieldではないんだよってことが書いてあるんですかね...。 カスタムフィールドの値が保存されるタイミングというのがイマイチ分かりませんでした..(´;ω;`) get_fieldだと$_POSTに値が登録された後のものが取得できて、$_POST['acf']['fields_01234']を使うと値が登録される前のものが取得できるってことなんでしょうか? (そこに関しても違いがわからないのですが(´;ω;`))
guest

回答2

0

ベストアンサー

save_postを使ったらどうでしょうか。
https://codex.wordpress.org/Plugin_API/Action_Reference/save_post

追記

無視?
何か反応あってもよくない?

get_fieldやとDBに保存したものしか取れんのが原因。
だからこう。

$cal_fields = get_field("switch", $post->ID); ↓ $cal_fields = $_POST['fields']['フィールドキー'];

これでもええんちゃうかと思うけど?

function makes_json( $post_id, $post, $update ) { if (function_exists('xdebug_disable')) { xdebug_disable(); } if( $post->post_status === 'publish' ) { // Get ALL Posts $args = array( 'numberposts' => -1, 'orderby' => 'post_date', 'order' => 'DESC', ); $posts = get_posts($args); $homeUrl = 'http:test.jp/static_directory'; if (count($posts) == 0) { return; } foreach ($posts as $post) { $cal_fields = get_field("switch", $post->ID); $output_json[date('Ym', strtotime($post->post_date))][] = array( 'title' => $post->post_title, 'start' => $post->post_date, 'url' => $homeUrl . '/archives/' . $post->ID, 'value' => $cal_fields, ); } // Get Upload Directory $upload_dir = wp_upload_dir(); $upload_dir = $upload_dir['basedir'].'/json'; // Create Directory if (file_exists($upload_dir) == FALSE) { mkdir($upload_dir, 0777); } // Delete All JSON Files array_map('unlink', glob($upload_dir.'/*.json')); // Create JSON Files foreach ($output_json as $key => $value) { file_put_contents($upload_dir . '/'.$key.'.json', json_encode($value)); } } } add_action('save_post', 'makes_json', 99, 3);

投稿2018/01/08 01:32

編集2018/01/08 05:11
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Yashichi

2018/01/08 05:14 編集

このsave_post関数と現在使ってるtransition_post_statusの違いがイマイチ分かりません(´°̥̥̥̥̥̥̥̥ω°̥̥̥̥̥̥̥̥`)
退会済みユーザー

退会済みユーザー

2018/01/08 05:37

コーデックス読めば解ると思うけど? カスタムフィールドの中身の有無による結果の違い save_postはDBに保存した後に実行するからget_fieldで値が取れる transition_post_statusは未保存の場合、値が無い所へget_fieldを実行するので何も取れない 保存前にカスタムフィールドの値を取りたいなら$_POSTから取る。 だから $cal_fields = get_field("switch", $post->ID); ↓ $cal_fields = $_POST['fields']['フィールドキー']; save_postでもどっちでも好きな方でどうぞ。
Yashichi

2018/01/08 05:55

ありがとうございます。 $_POST['fields']['フィールドキー']を使うと保存前のカスタムフィールドの値が取得できることは確認できました。しかしながら、$_POST['fields']でvar_dumpしてみると、 あらゆるカスタムフィールドの値が、新規投稿したときのカスタムフィールドの値と同じになってしまいます。 これは、DB未保存の値の取得($_POST["fields"]["フィールドキー"])だけでは足りないということなのでしょうか。。
退会済みユーザー

退会済みユーザー

2018/01/08 06:32 編集

じゃあ有無を確認したら? if( ! empty( get_field("switch", $post->ID) ) ) { $cal_fields = get_field("switch", $post->ID); } else { $cal_fields = $_POST['fields']['フィールドキー']; } get_fieldで何か取れればそれにして何も取れなければ$_POSTから。
Yashichi

2018/01/08 07:30

ありがとうございます。 最終的に、今度は投稿の更新時に値が反映されなくなってしまって、二回更新したらそれができるという状態になりました。一旦save_postを使ったコードに書き換えてみようと思います。
退会済みユーザー

退会済みユーザー

2018/01/08 07:57

>今度は投稿の更新時に値が反映されなくなってしまって 『今度は』じゃなくてそれは最初からでは?
Yashichi

2018/01/08 08:02

最初は投稿の「新規作成時のみ」値が反映されなかったので、という意味ですね
退会済みユーザー

退会済みユーザー

2018/01/08 08:12

提示されたコードだと記事の更新時も更新前の値を持って来るから『今度は』ではなく最初から。 一度更新すると値を書き換えるがその時は取得できず、その後の更新で書き換えた値を取得する。 自分が示した改善策が悪いのではなく、貴方の書いたコードがそうさせているだけ。 だから『今度は』ではない。
Yashichi

2018/01/08 08:23

switch文に'publish'も入れてるからってことですよね。 現状、そもそもswitch文が、コード全体を囲んでいるから、 その範囲をカスタムフィールドの値取得部分にまで縮めた上で、 switchの分岐を"publish"とそれ以外に分けてみます。 ありがとうございます。
退会済みユーザー

退会済みユーザー

2018/01/08 08:37

>switch文に'publish'も入れてるからってことですよね 多分関係ないと思うけど
Yashichi

2018/01/08 09:02

すみません、記事の更新時も更新前の値を持ってくるというのは、foreachの終わりにreset_postdataを使ってないからってことなんでしょうか..
退会済みユーザー

退会済みユーザー

2018/01/08 09:54

2つ前のコメントに書いてますが? そもそも新規投稿でget_fieldで値が取れないのは【DBに保存する前】だから。 更新の場合も更新した値を【保存する前】にget_fieldを実行して取得しているからファイルの中身に変化が無い。 その次に更新を押した時に【現在保存されている値】を取得してファイルを生成するするから二回更新したら反映したように感じるだけ。
退会済みユーザー

退会済みユーザー

2018/01/08 11:00

こうすれば? if( get_the_ID() === $post->ID ) { $cal_fields = $_POST['fields']['フィールドキー']; } else { $cal_fields = get_field("switch", $post->ID); } get_the_ID()の結果と$post->IDが同じ場合は$_POSTからカスタムフィールドを取ってそれ以外は保存された値を取る。
Yashichi

2018/01/08 11:41

うまくいきました... get_the_ID()が取得するIDは現在の投稿のものだから、つまり最新の投稿で $post->IDで取得できるIDはまさしく自分が今編集・投稿したもののIDだから、 これが一致する場合ってのは新規作成の投稿で 一致しない場合ってのはそれ以外の例えば更新とかになるってことですね すみません、ありがとうございます...
退会済みユーザー

退会済みユーザー

2018/01/08 11:58

新規作成だけではなく現在更新中のポストも含む意味ですが。 現在開いている記事入力画面の記事のポストIDを取って一致する記事は$_POSTからカスタムフィールドを取る、そうではない記事はDBから取る。 だから古い記事でもポストIDが一致したら$_POSTから取る、これで更新時も対応可能ってこと。
guest

0

回答ではない補足です。

https://support.advancedcustomfields.com/forums/topic/why-isnt-acfsave_post-firing/

こちらのURLで言及のある「field key of your custom field」の管理画面からの確認方法です。

  1. 管理画面 > カスタムフィールド > 「フィールドグループを編集」画面を開く
  2. 「表示オプション」を開いて、「フィールド Show Field Key:」で「はい」を選択

これで各フィールドのフィールドキーが一覧に表示されるようになります。

投稿2018/01/08 10:36

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Yashichi

2018/01/08 11:43

関数で確認してました... ありがとうございます
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問