これまで WordPress のプラグインやテーマのインストール、更新、削除などには FTP が使われてきましたが、
セキュアな通信とは言えないので可及的速やかにやめましょう。やるのであれば SSH を使った通信をするべきです。
といいつつ、実は SSH すら必要ない、ということがわかりましたのでまとめました。
所有者/グループの設定
WordPress のフォルダ・ファイル群の所有者とグループを Apache の実行ユーザー、グループに設定します。
$ sudo chown -R apache:apache /path/to/wordpress
この状態で、もう一度プラグインやテーマのインストールをしてみましょう。
さくっとインストールできると思います。
FTP, SFTP, SSH, direct など複数種類ありますが、今回の所有者・グループの変更によって選択される通信方法は direct です。
direct の設定はあまりよくないイメージを持たれている方もいるかも知れませんが、別に wp-config.php で明示的に指定しているわけでもないし、WordPress が「だいじょうぶ」と判断したので結果として direct になっているだけで、特に問題ない認識です。
って切り捨てるのもあれなので、コードを読みました。
プラグイン・テーマのインストール/アンインストール時、本体のアップデート時などでファイルの取得方法を取得するために get_filesystem_method() が必ず呼ばれます。 該当箇所だけ抜粋します。
https://core.trac.wordpress.org/browser/trunk/src/wp-admin/includes/file.php#L1563
if ( ! $method ) {
$temp_file_name = $context . 'temp-write-test-' . time();
$temp_handle = @fopen($temp_file_name, 'w');
if ( $temp_handle ) {
// Attempt to determine the file owner of the WordPress files, and that of newly created files
$wp_file_owner = $temp_file_owner = false;
if ( function_exists('fileowner') ) {
$wp_file_owner = @fileowner( __FILE__ );
$temp_file_owner = @fileowner( $temp_file_name );
}
if ( $wp_file_owner !== false && $wp_file_owner === $temp_file_owner ) {
// WordPress is creating files as the same owner as the WordPress files,
// this means it's safe to modify & create new files via PHP.
$method = 'direct';
$GLOBALS['_wp_filesystem_direct_method'] = 'file_owner';
} elseif ( $allow_relaxed_file_ownership ) {
// The $context directory is writable, and $allow_relaxed_file_ownership is set, this means we can modify files
// safely in this directory. This mode doesn't create new files, only alter existing ones.
$method = 'direct';
$GLOBALS['_wp_filesystem_direct_method'] = 'relaxed_ownership';
}
@fclose($temp_handle);
@unlink($temp_file_name);
}
}
コードを見る限り、テンポラリのファイルを作成し、そのテンポラリファイルの所有者と file.php の所有者を比較して$method を direct にしています。
テンポラリのファイルは PHP が作成していますが、PHP は Apache のモジュールとして動いているため実行ユーザーは Apache の実行ユーザーとなり、
結果的にテンポラリファイルの所有者は Apache の実行ユーザーとなります。
つまり WordPress のファイル群の所有者を apache にしておけば、そもそも通信方法を選択するモーダル自体でてこない、ということになります。
参考:WordPressのアップグレードやプラグインの更新をFTP画面なしで行う方法
まず呼ばれるのは wp-admin/theme-install.php
テーマのインストールページに行き、試しに適当なテーマのインストールボタンをクリックしてモーダルを表示してみたりします。
(このときデベロッパーツールなどで通信や要素を確認する)
モーダル要素の id が request-filesystem-credentials-dialog になっていることがわかったので php ファイルから該当箇所を検索します。
https://core.trac.wordpress.org/browser/trunk/src/wp-admin/includes/file.php#L1915
function wp_print_request_filesystem_credentials_modal() {
$filesystem_method = get_filesystem_method();
ob_start();
$filesystem_credentials_are_stored = request_filesystem_credentials( self_admin_url() );
ob_end_clean();
$request_filesystem_credentials = ( $filesystem_method != 'direct' && ! $filesystem_credentials_are_stored );
if ( ! $request_filesystem_credentials ) {
return;
}
?>
<div id="request-filesystem-credentials-dialog" class="notification-dialog-wrap request-filesystem-credentials-dialog">
<div class="notification-dialog-background"></div>
<div class="notification-dialog" role="dialog" aria-labelledby="request-filesystem-credentials-title" tabindex="0">
<div class="request-filesystem-credentials-dialog-content">
<?php request_filesystem_credentials( site_url() ); ?>
</div>
</div>
</div>
<?php
}
どうやらここっぽいので、 wp_print_request_filesystem_credentials_modal() を呼んでいる箇所を洗います。すると、 theme-install.php で呼ばれていることがわかりました。
https://core.trac.wordpress.org/browser/trunk/src/wp-admin/theme-install.php#L366
^ ここですね。
だいたいこんな感じで特定することができました。
モーダルの表示に通信は発生しない
テーマの「インストール」ボタンをクリックしたときにモーダルが表示されて、その際に通信が発生しないことの調べがついていたので、 JavaScript の onclick あたりで制御してるんだろうなっていう予測を立てます。
対象の要素は theme-install class が付加されています。
wp_enqueue_script( 'theme' ); でテーマの JS を読み込んでいることがわかるので対象の JS ファイルを探します。
https://core.trac.wordpress.org/browser/trunk/src/js/_enqueues/wp/theme.js#L378
しっかり onclick が設定されています。
https://core.trac.wordpress.org/browser/trunk/src/js/_enqueues/wp/theme.js#L603
installTheme: function( event ) {
var _this = this;
event.preventDefault();
wp.updates.maybeRequestFilesystemCredentials( event );
$( document ).on( 'wp-theme-install-success', function( event, response ) {
if ( _this.model.get( 'id' ) === response.slug ) {
_this.model.set( { 'installed': true } );
}
} );
wp.updates.installTheme( {
slug: $( event.target ).data( 'slug' )
} );
},
この installTheme() が呼ばれるので追っていくと、以下にたどり着きます。
https://core.trac.wordpress.org/browser/trunk/src/js/_enqueues/wp/updates.js#L1501
wp.updates.requestForCredentialsModalOpen = function() {
var $modal = $( '#request-filesystem-credentials-dialog' );
$( 'body' ).addClass( 'modal-open' );
$modal.show();
$modal.find( 'input:enabled:first' ).focus();
$modal.on( 'keydown', wp.updates.keydown );
};
.request-filesystem-credentials-dialog {
display: none;
/* The customizer uses visibility: hidden on the body for full-overlays. */
visibility: visible;
}
というわけで、いろいろ話は脱線しましたが理解が深まりました。
WordPress よくできてますよね。
mac に pip をインストールする
mac は標準で python が入っていますが、パッケージ管理の pip がインストールされていないので入れてみました。
2017/05/26 09:00
[GAS] Google Drive の特定フォルダ配下のフォルダ・ファイルの権限を一括で移譲する
Google Drive の特定フォルダ配下のファイル・フォルダの権限を一括で移譲するツールを Google Apps Script で作りました。
2018/11/10 15:54
[Windows] Ophcrack を使ってユーザーパスワードを解析する方法
家族で使っていた Windows7 のログインパスワードを忘れたため、Ophcrack を使って解析したときの記録です。
2017/09/30 21:00
[shell] フォルダ内にある大量の ZIP ファイルをまとめて解凍する
とある ZIP を解凍すると中に大量の ZIP が居たときに幸せになれるコマンドを紹介します
2018/06/19 23:45
[MySQL] データファイルから DB を復元する
先日 MySQL が再起動できなくなる問題が発生し、急遽データファイル(.frm, .ibd)から復元しました
2018/11/25 12:44