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

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

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

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

PHP

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

Q&A

解決済

2回答

2225閲覧

公開中の記事を公開したまま編集して別ブランチで承認待ちにしたいが、WordPressのアクションフックの引数がリファレンスのものと比べて足りない

threeaster

総合スコア14

WordPress

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

PHP

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

0グッド

0クリップ

投稿2019/02/15 12:06

前提・実現したいこと

公開中の記事を公開したまま、編集して承認待ちにできるようにしたい。
なので、
https://www.nishi2002.com/10468.html
のような方法で、ブランチを作って別記事として作って、それを編集してもらうという形にしたい。
しかし、上の記事で使っているプラグイン「WP Post Branches」は最新3回のメジャーリリースに対してテストされていないので、
今回の案件では使えません。
https://ja.wordpress.org/plugins/wp-post-branches/
なので、これと同じようなものを作ろうとおもいました。
(実際に作りたいものは公開権限がない人は公開済みのものを編集するときは、公開する事ができず、強制的にブランチを切って承認待ちとして保存するようにしたいので、WP Post Branchesを改造する形になります。)

上の調査過程で、また別の機能を実装しているときに、アクションフックやフィルターフックの引数がリファレンスのものと比べて足りません。これがどうして起こっているのかが知りたいです。こちらの疑問を解消したいというのがどちらかというと主題です。下で見ているようにリファレンスのほうが間違っているような気がするのですが、正しい情報はどこかで見ることができるでしょうか? また、これはいつからこうなっているのでしょうか?

発生している問題・エラーメッセージ

まず、WP Post Branchesでは「ブランチを作成」を押したときにはore_post_updateフックで、編集された投稿をコピーして、新しい投稿として保存しています。その後リダイレクトしてexitすることで、元の記事に対する編集はしないようになっています。ざっと下のような処理をしています。

php

1add_filter('pre_post_update', function($id){ 2 if(isset($_POST['wp_post_branches'])){ // wp_post_branchesは「ブランチを作成」のname 3 $pub = get_post($id); 4 // $pubのIDを除いた項目をコピーして、名前にブランチであることを追加し、post_statusを変更する 5 $draft_id = wp_insert_post($put); 6 // その後postmetaやtaxonomyもコピーする 7 add_post_meta($draft_id, '_wpbs_pre_post_id', $id); // コピー元のidを保存しておく 8 wp_safe_redirect(admin_url('post.php?post=' . $draft_id . '&action=edit')); 9 exit; 10 } 11});

しかし、ここで取得した$pubは、変更前の情報しか入っていないので、これを実行しても、新しく作った投稿は、編集前のコピーになってしまいました。
なので、編集前と編集後の情報を取れるpost_updatedを使えないかなと思いました。(今書きながら、post_updatedだと元の記事を変更してしまうので、この方法は使えないなと思いました。別の手段で実装することになると思います。)
しかし、post_updatedリファレンス
https://codex.wordpress.org/Plugin_API/Action_Reference/post_updated
では3つの変数を取るはずなのに、以下のようにしてみると、1つしか変数をとっていないように見えます。

php

1add_filter('post_updated', function($id, $post_after, $post_before){ 2 wp_die(var_export($id, true) . '/' . var_export($post_after, true) . '/' . var_export($post_before, true)); 3});

実行結果

Fatal error: Uncaught ArgumentCountError: Too few arguments to function {closure}(), 1 passed in /Users/[user_name]/[project_name]/wp-includes/class-wp-hook.php on line 288 and exactly 3 //以下、スタックトレースが続く

上はPHP7.2.10でのエラーなのですが、当初PHP5.6.37でやっていて、そのときは以下のようなエラーが出ます。

Warning: Missing argument 2 for {closure}() in /Users/[user_name]/[project_name]/wp-content/themes/[theme_name]/inc/functions/branch.php on line 149 Warning: Missing argument 3 for {closure}() in /Users/[user_name]/[project_name]/wp-content/themes/[theme_name]/inc/functions/branch.php on line 149 Notice: Undefined variable: post_after in /Users/[user_name]/[project_name]/wp-content/themes/[theme_name]/inc/functions/branch.php on line 150 Notice: Undefined variable: post_before in /Users/[user_name]/[project_name]/wp-content/themes/[theme_name]/inc/functions/branch.php on line 150 201/NULL/NULL

inc/functions/branch.phpfunctions.phpからrequire_onceされているファイルで、ブランチ関係のものが入っています。また、201はコピー元のpost_idです。
ちなみに以下だとErrorやWarningが出ません。

php

1add_filter('post_updated', function($id){ 2 wp_die(var_export($id, true)); 3});

試したこと

これはいろいろカスタマイズがされたWordPressで試したのですが、その後、インストールしたばかりでプラグインなども有効にしていないもので試しても同じでした(WP_DEBUGなどの指定が不完全だったのか、最後の201/NULL/NULLに相当するところしか出ませんで
したが。また、Wordpress5の新しいエディタだと更新はajaxで行うようなので、表には出てこなかったのでchromeのコンソールで確認しました)。

また、post_updated以外にも、例えばuser_has_capでもリファレンスでは3引数取るはずなのに
https://codex.wordpress.org/Plugin_API/Filter_Reference/user_has_cap
1引数しか取得できず、rest_{$this->post_type}_queryでもリファレンスでは2引数取るはずなのに
https://developer.wordpress.org/reference/hooks/rest_this-post_type_query/
1引数しか取得できませんでした。

wp-includesではどうなっているのだろうと調べたのですが、wp-includes/default-filters.phpでは

php

1add_action( 'post_updated', 'wp_save_post_revision', 10, 1 );

wp-save_post_revisionを読んでいて、これはwp-includes/revision.phpにありますが、

php

1function wp_save_post_revision( $post_id ) { 2 //... 3}

となっているので仕様のようです。
ただ、googleでwordpress アクションフック 引数 足りないとかで調べても情報が出てこないので、もしかしたら私の環境だけ変になっているのではないかという考えも捨てきれていません。(単に調べ方が悪いだけだとは思いますが)

補足情報(FW/ツールのバージョンなど)

MAMP 5.2(351)
PHP7.2.10
MySQL5.7.23
Apache2.2.34
macOS Mojave 10.14.2

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

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

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

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

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

guest

回答2

0

ベストアンサー

[PHP 7.0.x から PHP 7.1.x への移行 下位互換性のない変更点]
(http://php.net/manual/ja/migration71.incompatible.php)に記載されている

関数に渡す引数が少ない場合の挙動
これまでのバージョンでは、ユーザー定義の関数に渡す引数が足りない場合は warning が発生していました。PHP 7.1 以降では、warning ではなく Error 例外が発生するようになります。 この変更はユーザー定義の関数に対してだけのもので、 内部関数には影響を及ぼしません。

の影響ですね。

add_filter('post_updated', function($id, $post_after, $post_before){ wp_die(var_export($id, true) . '/' . var_export($post_after, true) . '/' . var_export($post_before, true)); }, 10, 3);

のように、オプションとなっている引数を指定して、呼び出すとどうでしょうか。

関数リファレンス/add_filter 参照

post_updated 参照


また、pre_post_update も引数は、2つ取れるので

add_filter('pre_post_update', function($id,$data){ wp_die(var_export($id, true) . '/' . var_export($data, true)); }, 10, 2 );

のように呼び出すとどうなるでしょうか?

投稿2019/02/15 22:07

CHERRY

総合スコア25171

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

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

threeaster

2019/02/15 23:07

動きました。ありがとうございます。 add_filter及びadd_actionの第4引数で引数の数を調節できる、しなければいけないということがわかっておらず、 常にリファレンスに書かれた数の引数がくるものだと思っていました。
guest

0

斜め読みしかしてませんが

php

1add_filter( 2 'post_updated', 3 //argument 1 4 function($id, $post_after, $post_before){ 5 wp_die(var_export($id, true) . '/' . 6 var_export($post_after, true) . '/' . 7 var_export($post_before, true)); 8 }//, 9 // argument 2, 10 // argument 3 11);

ってことじゃないですか?

投稿2019/02/15 12:49

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

threeaster

2019/02/15 15:59

そういうわけではないと思います。 ``` add_filter('post_updated', function($id){ wp_die(var_export($id, true)); }); ``` が、エラーになっていませんし、その数え方だと`post_updated`がargument1、functionがargument2になると思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問