テーマやプラグインの更新(アップグレード)時に自動でこっそりバックアップをとる

main_backup
カスタマイズしていたテーマやプラグインの更新 (アップグレード) をする際に
バックアップもとらずについうっかり「更新」ボタンを押してしまった事はありませんか?

特にクライアント側で「更新」されてから 連絡があったら。。。最新のバックアップ探しからはじめなければなりません。
特に公式テーマベースでカスタマイズし、納品後に知らないところでクライアントが内容を変更されていた場合は目もあてられません。
そこで、テーマやプラグインの更新中に自動でバックアップとるアクションフィルターを考えました。

 

backup-2

 

概要

テーマやプラグインのアップグレードの途中でファイルを入れ替える前に、指定の名前のフォルダ以下全部をバックアップフォルダへコピーをとります。
フォルダが無い場合は新規作成され、すでにバックアップファイルがある場合は上書きされます。もしフォルダ作成やコピーが失敗するとエラーとなりアップグレード自体もされません。

管理画面上ではバックアップ成功の場合は「成功した!」等の表示はされません。(確認したい場合はFTPで確認してください。)
テーマやプラグインの更新 (アップグレード) の時だけバックアップを取りますので、手動で「削除してから新規追加」されるとバックアップはとりません。

 
 

コード

以下のコードを my-plugin.php に張り付けてください。

/*
 * Backup of automatic with the old plugins or themes.

 * @param string      $source        File source location.
 * @param string      $remote_source Remove file source location.
 * @param WP_Upgrader $install       WP_Upgrader instance.
 * @return $source or WP_Error.
 * Version: 1.0.0
 * License: GPLv2 or later
 */
function nendebcom_old_plugin_theme_backup( $source, $remote_source, $install ){

	global $wp_filesystem;
	$backup_from_folder = '';

	//If the processing of PHP has timed out.
	//@set_time_limit( 300 );

	//Plugin or theme folder-name that you want to back up.
	$folder_names = array( 'twentyten', 'akismet' );

	//Backup Base Folder.
	$backup_base_folder = ABSPATH . 'backup';

	foreach( $folder_names as $folder_name ){

		$backup_to_folder   = $backup_base_folder . '/' . $folder_name . '';

		//plugin
		if( isset( $install->skin->plugin ) || isset( $install->skin->plugin_info ) ){
			$backup_from_folder	= ABSPATH . 'wp-content/plugins/' . $folder_name . '/';
		}
		//theme
		if( isset( $install->skin->theme )  || isset( $install->skin->theme_info ) ){
			$backup_from_folder	= ABSPATH . 'wp-content/themes/'  . $folder_name . '/';
		}

		if ( false !== strpos( $source, '/' . $folder_name . '/' ) && !empty( $backup_from_folder ) ){

			//Existence confirmation of the plugin file
			if ( $wp_filesystem->exists( $backup_from_folder ) ) {

				//Create backup folder.
				if ( ! $wp_filesystem->exists( $backup_base_folder ) ) {
					if ( ! $wp_filesystem->mkdir( $backup_base_folder, FS_CHMOD_DIR ) ) {
						return new WP_Error( 'mkdir_failed_destination', "バックアップフォルダを作成できませんでした。", $backup_base_folder );
					}
				}

				//Create htaccess file.
				if ( ! $wp_filesystem->exists( $backup_base_folder. '/.htaccess' ) ) {
					$htaccess_txt = 'Order deny,allow' . PHP_EOL . 'Deny from all' . PHP_EOL;
					if ( ! $wp_filesystem->put_contents( $backup_base_folder. '/.htaccess' , $htaccess_txt, FS_CHMOD_FILE ) ){
						return new WP_Error( 'htaccess_failed_destination', "htaccessファイルを作成できませんでした。");
					}
				}

				//Create plugin or theme folder.
				if ( ! $wp_filesystem->exists( $backup_to_folder ) ) {
					if ( ! $wp_filesystem->mkdir( $backup_to_folder, FS_CHMOD_DIR ) ) {
						return new WP_Error( 'mkdir_failed_destination', "バックアップフォルダを作成できませんでした。", $backup_to_folder );
					}
				}

				// Copy old version of item into place.
				$result = copy_dir( $backup_from_folder, $backup_to_folder );
				if ( is_wp_error( $result ) ) {
					return new WP_Error( 'copy_failed_destination', "バックアップできませんでした。", $backup_from_folder  );
				}
			}
		}
	}
	return $source;
}
add_filter( 'upgrader_source_selection', 'nendebcom_old_plugin_theme_backup', 10, 3 );

 

 

設定

必要に応じて上記コード内を変更してください。

バックアップをとる テーマ か プラグイン のフォルダ名を設定してください。

【サンプル】

	//Plugin or theme folder-name that you want to back up.
	$folder_names = array( 'twentyfifteen', 'akismet' );

フォルダ名とは wp-content/themes か wp-content/plugins の下にあるテーマやプラグインのフォルダ名の事です。プラグイン名とフォルダ名が微妙に違う場合がありますので注意してください。
テーマやプラグインのフォルダ名はカンマ区切りで複数設定できます。
この例の場合は twentyfifteen(テーマ) と akismet(プラグイン) になります。

バックアップを設置する場所を設定してください。

【サンプル】

	//Backup Base Folder.
	$backup_base_folder = ABSPATH . 'backup';

この場合は WordPress設置場所/backup になります。

*backupフォルダには .htaccess が設置され それ以下の階層は保護されますが、もしWEBではアクセスできないドキュメントルートより上の階層へFTPでアクセスできる場合は その場所を backup設置場所 になるように 「ABSPATH . ‘backup’」 の所をフルパスで指定してやるとより安心です。
【サンプル】
 ドキュメントルートのフルパスを
 /home/xxxxxxxxx/www/public_html/
 として、WordPress設置フォルダのフルパスは
 /home/xxxxxxxxx/www/public_html/wp/
 とすると 「ABSPATH . ‘backup’」の バックアップ設置フォルダのフルパスは
 /home/xxxxxxxxx/www/public_html/wp/backup/
 になります。

 この場合のドキュメントルートより上の階層に設置できた場合のバックアップのフルパスは
 /home/xxxxxxxxx/www/backup/
 とすると以下のようになります。

	$backup_base_folder = '/home/xxxxxxxxx/www/backup/';

 または、こちらでもいけるかもしれません。

	$backup_base_folder = ABSPATH . '../../backup';

 
 

注意事項

サーバーによっては .htaccess が効かなかったりパーミッションが変だったり考えられますので
ちゃんとバックアップがとれているか 一応全バックアップをとってから必ずテストしてくださいね。

 
 

参考

WordPress Code Reference upgrader_source_selection
https://developer.wordpress.org/reference/hooks/upgrader_source_selection/

WordPress Codex Filesystem API
http://codex.wordpress.org/Filesystem_API