WordPress のFilesystemとかAjaxとか
Page No.2
ところでと・・・。
管理画面の中であれば、使用方法はわかりました。
しかし、それならば通常のアクセスしたページにおいてはどうすればいいのだろうかと。
たとえば、アクセスログなんぞをとるときですね。
ネットでちょっと調べてみると、ちゃんと教えてくれている方がいてすぐに見つけることが出来ます。
これにて機能するということです。
ためしに以下のようなコードを作って、さきのテーマのオプションを読み込んだり設定したりするクラスの中にいれて、クラス読み込みの時に実行されるようにしてみました。
確かに、これでちゃんと機能します。
しかし、何度かやっていると意図に反していることに気が付きます。ファイルにデータが加えられて蓄積されているのではなく、常に一行だけのファイルになってしまうということ。
う~む、これはモードの問題か?と、思いつつ、こうなったら腰を据えてじっくりとファイルの中身を見てみようという気になります。
「WP_Filesystem() 」は「wp-admin/includes/file.php 」 の中に書かれています。
「get_filesystem_method() 」と「request_filesystem_credentials() 」も同じファイルです。
管理画面においてはcodex にあったものをそのまま使用したわけですが、その時は「request_filesystem_credentials() 」を使用していました。これに関しては、説明書きが
「Displays a form to the user to request for their FTP/SSH details in order to connect to the filesystem. 」
「ファイルシステムに接続するために、ユーザーに彼らのFTP/SSHに関しての詳細を要請するためにフォームを表示します。」
と、いう事だと思うので、普通にサイトにアクセスしてくる不特定の方々に対して使うことではないですね。
で、「WP_Filesystem() 」がなにをやっているかと探っていくと、
と、もう少しつづきますが、このあたりまででよさそうです。
まぁ、割とさっぱりしてます。やはり9行目のget_filesystem_method()がみそですね。
get_filesystem_method()の戻り値の$method がfalse であれば、すぐに処理を中止し、$method により得られるクラスが存在しない時はフィルターフックを用意しつつクラスの存在しうるファイル名を取得し、そのファイルが存在しなければこれまた処理を中止し、 あればファイルを読み込んで、$method により得られたクラスのインスタンスを作って変数$wp_filesystem に入れておくということです。
しかしてその「get_filesystem_method()」が何者かとみてみると、
注:下記英注釈の訳は全て私によるものです。
定数FS_METHOD の値を確認してくださいと書いてあるので自サイトとローカルな環境で確認してみましたが、いずれもfalse でした。と、いうのは当然ですね。これはwp-config にて設定する値であり、してないのでなくて当然です。codex を見ても、「一般にアップデートで問題が発生する場合にのみ変更してください。」と、書いてあるぐらいなので、定義していないのが普通なのでは。
と、いうことで20行目のif ( ! $method ) は大体において合致するもので、ここから53行目までが重要なところということだと思います。
WordPress により新規にファイルを作成し、そのファイルの所有者と、WordPress 自体のファイルの所有者が同じであれば、PHPによるファイルの変更や新規作成が安全であるということなんだそうですが、なんだかいまひとつよくわからないのです。
共有サーバーにおいて別の所有者のディレクトリにファイルを作るときに、果たしてこのシステムを動かしているのだろうかと。ただ単に、間違えてしまうことを避けるためだけのことなんだろうか。
まぁ、よくわかっていないから、頼っていたほうがいいんだろうと思います。
codex 「wp-config.php の編集」のページのFS_METHODのところでも最優先のデフォルトは”direct”ということですが、実際に$method の値はどうなのかと、自サイトとローカルで値を得てみるとやはりというか当然と言うことなのか”direct”でしたね。
と、いうことなので適用されているWP_Filesystem のクラスは、WP_Filesystem_Direct であり、ファイルはclass-wp-filesystem-direct.php だということがわかりました。
いざ、class-wp-filesystem-direct.php の中の、put_contents() を見てみると、思った通りですね。
と、fopen のモードが'wb'になっています。'w'はファイルポインタを先頭にするので、最後に追加ということにはなりえないです。この関数を見る限りにおいてはこのモードを変更することはできないです。他のクラスのファイルの中を調べてみても、それようの関数は見当たりませんでした。
さてどうしたものかと考えていると、そういえばWP_Filesystem にフィルターフックがあったなぁ、と。
WP_Filesystem の説明書きにも、
「Plugins may add extra transports, And force WordPress to use them by returning the filename via the {@see 'filesystem_method_file'} filter.」
「プラグインは、特別なトランスポートを追加し、そしてフィルタを介してファイル名を返すことによって(フィルターフック 'filesystem_method_file'を見るべし)、ワードプレスにそれらを使用するようにさせることができます。」
と、いう感じでしょうか。
あらためてWP_Filesystem() を見ると、get_filesystem_method()の戻り値$method によって得られるクラスを、実際に$wp_filesystem として使用するということです。そしてその部分にフィルターフックが用意してある。これは、このフィルターフックを使えば、使用させるクラスを書いたファイルをディレクトリを含めて指定できるものと思われます。
再び、あらためてget_filesystem_method()を見れば、最後にある、$method を引数として得られるフィルターフック 'filesystem_method' において、自分が作成したクラスを使用させるために、そのファイルの名前の固有の部分を$method として指定してやればできそうだと思われます。
どちらで指定するかですか、実際にやってみるとget_filesystem_method()のフィルターフック 'filesystem_method' を使って、$method の値を変更してもできます。ただしこの場合WordPress は指定されたファイル"class-wp-filesystem-$method.php" を、/wp-admin/includes/にて探しますから、$method には固有の文字列を指定し、その文字列にて識別できるファイルを/wp-admin/includes/に用意する必要があります。
また、WP_Filesystem() のフィルターフック 'filesystem_method_file' を使用しても、$method の値は”direct”のままで、自作のテーマフォルダにコピーして独自の関数をくわえたテーマフォルダにあるclass-wp-filesystem-direct.php を指定してやることでできました。
もちろん両方を使えば、$method の値も変更し、/wp-admin/includes/ではないフォルダにおいた"class-wp-filesystem-$method.php" のファイルを指定することも可能でした。
しかし、$method の値は変更せず(get_filesystem_method()のフィルターフック 'filesystem_method' は使用せずに)、WP_Filesystem() のフィルターフック 'filesystem_method_file' だけを使用して、独自の名前を付けた、たとえばclass-wp-filesystem-sanbanze.php といったファイルを、/wp-admin/includes/ではないフォルダにおいた場合、そのファイルを指定することはできませんでした。エラーが出てしまいます。コードを見る限りそれもできそうではあったのですが、ダメでした。
$method の値は、どうしてもそうすることが必要ということでないのなら、システム的にもあまり変更しないほうが良いような気がします。ただ、普通にサイトにアクセスするぶんには、ファイル操作などするわけも無く、file.php すら読み込んでいない状態なので、別段、なんら問題無いようにも思えます。正直なところ、よくわかりません。
まぁ、なんとなくではありますが、WP_Filesystem() のフィルターフック 'filesystem_method_file' を使用して、テーマフォルダにある独自の関数をくわえたclass-wp-filesystem-direct.php を指定してやる方法が良いように思いましたのでそれでやりました。
ただねぇ、これだと「Theme Check」からおしかりをうけてしまうのですが・・・ね。
とりあえず、/wp-admin/includes/にあるclass-wp-filesystem-direct.php を、我がテーマフォルダにコピーして、ファイルの最後に追加するためのadd_contents()関数をくわえました。
そして、フィルターフックにて呼び出す関数。
最後に、前述したアクセスログを保存する関数を訂正したもの。
フィルターフックは20行目です。
以上、しかし、長いな~!
もし、こんなのを最後まで読んで下さった方がいたとしたら、感激です。感謝!
Post : 2016/08/24 10:32