Linuxなどのメモ書き

WordPress メタボックスでファイルアップロード


概要

WordPress メタボックス追加サンプルコード」の続き。記事編集ページに、メタボックスでファイルアップロード機能を追加する処理の説明。

サンプルコードは以下。

https://github.com/kztomita/wordpress-plugin-sample-metabox

全体の説明は「WordPress メタボックス追加サンプルコード」を参照。

ファイルアップロード処理に関する説明

sample-metabox-admin-file.phpの説明。

sample-metabox-admin-file.phpは図1に示すメタボックスを追加する。本ファイルは、<input type="file" />を使ったファイルのアップロードを行う。アップロードしたファイルはメディアライブラリに登録せずに、記事編集ページのみで管理を行う。ファイルを再アップロードした場合は、旧ファイルを削除することで、ファイルの差し替えを行い、記事を削除した場合は、アップロード済みのファイルを削除する。

処理はsample-metabox-admin-checkbox.phpと同じく、メタボックスの表示処理と保存処理の二つに分かれる。

図1 sample-metabox-admin-file.phpが追加するメタボックス

 

メタボックス表示処理

function sample_metabox_add_file()
{
	wp_nonce_field('sample_metabox', 'sample_metabox_file_nonce');

	$id = get_the_ID();
	$post_meta = get_post_meta($id, SAMPLE_METABOX_METAKEY_FILE, true);
	if ($post_meta) {
		echo '<p><a href="'.$post_meta['url'].'" target="_blank">'.$post_meta['url'].'</a></p>';
	}

	$name = SAMPLE_METABOX_NAME_FILE;

	echo <<<END_OF_TEXT
<input type="file" name="{$name}" id="{$name}" value="" />
END_OF_TEXT;
	if ($post_meta) {
		echo <<<END_OF_TEXT
<label><input type="checkbox" name="{$name}_delete" id="{$name}_delete" value="1" />ファイルを削除</label>
END_OF_TEXT;
	}
}

function sample_metabox_add_meta_boxes_file()
{
	add_meta_box('id_sample_metabox_file', 'ファイルアップロード(PDF)', 'sample_metabox_add_file', 'post', 'normal', 'high');
}
add_action('add_meta_boxes', 'sample_metabox_add_meta_boxes_file');

/* ファイルアップロードに必要 */
function sample_metabox_edit_form_tag() {
	echo ' enctype="multipart/form-data"';
}
add_action('post_edit_form_tag', 'sample_metabox_edit_form_tag');

メタボックスの表示処理はチェックボックスのものとほぼ同じ。一点注意が必要なのは、<input type="file" />を使うため、formタグにenctype="multipart/form-data"を指定する必要がある。これは、post_edit_form_tagアクションで行っている。

ファイルアップロード処理

function sample_metabox_save_file($post_id)
{
	if (!isset($_POST['sample_metabox_file_nonce'])) {
		return;
	}
	if (!wp_verify_nonce($_POST['sample_metabox_file_nonce'], 'sample_metabox')) {
		return;
	}

	if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
		return;
	}

	/* 権限チェック */
	if (isset($_POST['post_type']) && 'page' == $_POST['post_type']) {
		if (!current_user_can('edit_page', $post_id)) {
			return;
		}
	} else {
		if (!current_user_can('edit_post', $post_id)) {
			return;
		}
	}

	/*
	 * ファイル削除を行うかチェック
	 */
	$post_meta = get_post_meta($post_id, SAMPLE_METABOX_METAKEY_FILE, true);
	if ($post_meta && $_POST[SAMPLE_METABOX_NAME_FILE.'_delete']) {
		@unlink($post_meta['file']);
		delete_post_meta($post_id, SAMPLE_METABOX_METAKEY_FILE);
		return;		/* 終了。アップロードは行わない。 */
	}

	/*
	 * アップロードされたファイルのチェック
	 */
	if(empty($_FILES[SAMPLE_METABOX_NAME_FILE]['name'])) {
		/* ファイルなし */
		return;
	}

	$file = $_FILES[SAMPLE_METABOX_NAME_FILE];

	$file_type = wp_check_filetype($file['name']);
	if ($file_type['ext'] != 'pdf') {
		wp_die('Unsupported file type. (Supported file type: .pdf)');
	}

	/* ファイル保存 */

	/* 旧ファイルがあれば削除 */
	if ($post_meta) {
		@unlink($post_meta['file']);
	}

	/*
	 * アップロードフォルダにファイル保存。
	 * 同名ファイルあれば、リネームされた名前が使われるので、
	 * 上書きされる心配はない。
	 * sanitize_file_name()も行われる。
	 */
	if (0) {
		$upload = wp_upload_bits($file['name'], null, file_get_contents($file['tmp_name']));
	} else {
		$overrides = array('test_form' => false);
		$upload = wp_handle_upload($file, $overrides);
	}

	if(isset($upload['error']) && $upload['error']) {
		wp_die('Upload error : '.$upload['error']);
	}

	$post_meta = array('file' => $upload['file'],
			   'url'  => $upload['url'],
			   'type' => $upload['type'],
			   );
	update_post_meta($post_id, SAMPLE_METABOX_METAKEY_FILE, $post_meta);
}
/*
 * save_post_{$post_type}のactionを使用
 * 全post_typeを対象にするなら、save_post actionを使用
 */
add_action('save_post_post', 'sample_metabox_save_file');

保存処理の前半では、チェックボックスの時と同じく、nonce、自動保存、権限のチェックを行う。その後、ここではPDFファイルのアップロードに限定しているため、wp_check_filetype()で拡張子をチェックし、アップロードされたファイルをuploadディレクトリに移動する。

ファイルをuploadディレクトリに移動する際は、wp_handle_upload()を使う。この関数はファイル名のチェック等を行った後、move_uploaded_file()でファイルをuploadディレクトリ以下に移動してくれる。同名ファイルが既にあれば、foo2.pngのような別名が使われるので、上書きされる心配はない。また、sanitize_file_name()も内部で行われる。

wp_handle_upload()ではなく、wp_upload_bits()を使っても問題ないが、推奨はwp_handle_upload()のようだ。

ファイルを移動後は、ファイルの情報をpost_metaに保存する。

 

記事削除時の処理

function sample_metabox_before_delete_post($post_id)
{
	global $post_type;
	if ($post_type != 'post')
		return;

	/* ファイルの削除 */
	$post_meta = get_post_meta($post_id, SAMPLE_METABOX_METAKEY_FILE, true);
	if ($post_meta) {
		@unlink($post_meta['file']);
	}

	/* post_meta情報自体はシステムの方で削除される */
}
add_action('before_delete_post', 'sample_metabox_before_delete_post');

アップロードしたファイルはメディアライブラリに登録していないため、記事を削除(ゴミ箱から削除)すると、アップロード済みのファイルが宙ぶらりんになってしまう。このため、記事削除時に対象記事のアップロードファイルも削除するようにしている。

メディアライブラリを使ったアップロードを行うメタボックスの説明

WordPress メタボックスでメディアライブラリ呼出し」へつづく。

 


最終更新 2015/12/22 02:01:14 - kztomita
(2015/12/22 01:18:56 作成)
添付ファイル
file_metabox.png - kztomita


リンク

その他のWiki
Linuxメモ
Xnuメモ

会社
(有)ビットハイブ
受託開発やってます。

よくやる仕事

・Webシステム開発(LAMP環境)
・Linuxサーバー設定関連
サーバー移転作業代行

開発事例にデジタルカタログ/マンガビューワーを追加しました。

draggable.jsのスマホ対応版デモページを追加しました。説明はこちら

検索

Adsense
最近のコメント