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

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

ただいまの
回答率

90.45%

  • PHP

    24611questions

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

  • WordPress

    9152questions

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

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

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 276

threeaster

score 4

前提・実現したいこと

公開中の記事を公開したまま、編集して承認待ちにできるようにしたい。
なので、
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することで、元の記事に対する編集はしないようになっています。ざっと下のような処理をしています。

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


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

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));
});


実行結果

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が出ません。

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

試したこと

これはいろいろカスタマイズがされた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では

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


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

function wp_save_post_revision( $post_id ) {
  //...
}


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

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

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

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+2

[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/16 08:07

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

    キャンセル

+1

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

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


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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/02/16 00:59

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

    キャンセル

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

  • ただいまの回答率 90.45%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • PHP

    24611questions

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

  • WordPress

    9152questions

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

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