WordPressを魔改造してたら、もう何がなんだか。

##おきまりのやつ
こんにちは・・・！
[CYBIRDエンジニア Advent Calendar](http://qiita.com/advent-calendar/2014/cybird)5日目の[@yuta_hosokawa](http://qiita.com/hosokawa-yuta)です。

最近、野球をはじめました。
28歳になってから始めるスポーツでもすごく楽しいですね！！
体を動かすのはほんと気持ちいいですよー！

4日目は@to-takahashiさんの[バイナリとわたし](http://qiita.com/to-takahashi/items/99fc05073994f43673ba)でした。

>運動などをして体が疲れた状態になっていると頭の回転があがる

なるほど・・・。体を動かすことが大事と・・・フロア中、走り回りたい・・・



--

## 本日の要約
WordPressで日々運用していると画像ファイルが山ほどの量になっており、サーバが悲鳴をあげていた。
コストも削減したいし・・・履歴をもっておいて管理してたいし・・・。
企画者も簡単に画像の差し替えできるような環境を作りたい・・・。
という問題もあり、WordPressからAmazon S3にファイルをアップロードできるように拡張してみました。
(Amazon S3とは：AWSが提供しているオンラインストレージサービス です。http://aws.amazon.com/jp/s3/)
([AWS SDK for PHP](http://aws.amazon.com/jp/sdkforphp/)：使用)

##やってみよう

AmazonSDKのAmazonS3の拡張したクラスを用意しておく


 ```PHP
<?php
class s3hoge{
	private $bucket = null;	// バケット名
	function __construct($bkt = null) {
		if(isset($bkt)){ 
			$this->bucket = $bkt;
		}
	}

	public function uploadFile($tofile,$upfile,$cntTyp){
		$response = $this->create_object(
						$this->bucket,
						$tofile, 
						array(
							"fileUpload" => $upfile,
							"acl" => AmazonS3::ACL_PUBLIC, //全体公開の状態
							"contentType" => $cntTyp
						)
					);
		if (!$response->isOK()) {
			return false;
		}
		return true;
	}
}
?>
 ```



WordPressで[media_handle_upload](http://codex.wordpress.org/Function_Reference/media_handle_upload)というmedia.phpにファイルがポストされた時のハンドリングを行う関数があるのでその中でuploadFileを呼ぶ。

ファイル場所
>Source File
media_handle_upload() is located in wp-admin/includes/media.php



 ```PHP
<?php
function media_handle_upload($file_id, $post_id, $post_data = array(), $overrides = array( 'test_form' => false )) {

	$time = current_time('mysql');
	if ( $post = get_post($post_id) ) {
		if ( substr( $post->post_date, 0, 4 ) > 0 )
			$time = $post->post_date;
	}

	$name = $_FILES[$file_id]['name'];
	$file = wp_handle_upload($_FILES[$file_id], $overrides, $time);

	if ( isset($file['error']) )
		return new WP_Error( 'upload_error', $file['error'] );

	$name_parts = pathinfo($name);
	$name = trim( substr( $name, 0, -(1 + strlen($name_parts['extension'])) ) );

	$url = $file['url'];
	$type = $file['type'];
	$file = $file['file'];
	$title = $name;
	$content = '';


//============================ add

	// add　aws S3 upload
	$sthemdl = new s3hoge(“バケット名”);	

	// s3フォルダ名
	$dir = $_POST["st_folder"];	// 

	$sthemdl->uploadFile($dir.$_FILES["async-upload"]["name"],$file,$type);


//============================ add end

    
	// use image exif/iptc data for title and caption defaults if possible
	if ( $image_meta = @wp_read_image_metadata($file) ) {
		if ( trim( $image_meta['title'] ) && ! is_numeric( sanitize_title( $image_meta['title'] ) ) )
			$title = $image_meta['title'];
		if ( trim( $image_meta['caption'] ) )
			$content = $image_meta['caption'];
	}

	// Construct the attachment array
	$attachment = array_merge( array(
		'post_mime_type' => $type,
		'guid' => $url,
		'post_parent' => $post_id,
		'post_title' => $title,
		'post_content' => $content,
	), $post_data );

	// This should never be set as it would then overwrite an existing attachment.
	if ( isset( $attachment['ID'] ) )
		unset( $attachment['ID'] );

	// Save the data
	$id = wp_insert_attachment($attachment, $file, $post_id);
	if ( !is_wp_error($id) ) {
		wp_update_attachment_metadata( $id, wp_generate_attachment_metadata( $id, $file ) );
	}

	return $id;

}
?>
 ```


s3のフォルダをWordPressメディア画面から取得したいときは、media-new.phpのinputタグを追加。


 ```PHP

<div class="wrap">
	<?php screen_icon(); ?>
	<h2><?php echo esc_html( $title ); ?></h2>

	<form enctype="multipart/form-data" method="post" action="<?php echo admin_url('media-new.php'); ?>" class="<?php echo $form_class; ?>" id="file-form">
		<span class="breadcrumb-segment">All Buckets</span> /
		<span class="breadcrumb-segment breadrumb-link clickable">bfb-news</span>
	<br>
	保存先フォルダ：<input id="st_folder" name="st_folder" type="text" value="hoge/"/>	
	<br>
	<br>
	<?php media_upload_form(); ?>

	<script type="text/javascript">
	var post_id = <?php echo $post_id; ?>, shortform = 3;
	</script>
	<input type="hidden" name="post_id" id="post_id" value="<?php echo $post_id; ?>" />
	
	<?php wp_nonce_field('media-form'); ?>
	<div id="media-items" class="hide-if-no-js"></div>
	</form>
</div>


 ```


画像をアップロード時にフォルダ名を取得できるようにhandlers.jsに"st_folder"を取得できるように追加

 ```js
	// init and set the uploader
	uploader_init = function() {

		// フォルダ名を取得
		wpUploaderInit['multipart_params']["st_folder"] = document.getElementById("st_folder").value;
		uploader = new plupload.Uploader(wpUploaderInit);

		$('#image_resize').bind('change', function() {
			var arg = $(this).prop('checked');

			setResize( arg );

			if ( arg )
				setUserSetting('upload_resize', '1');
			else
				deleteUserSetting('upload_resize');
		});

		uploader.bind('Init', function(up) {
			var uploaddiv = $('#plupload-upload-ui');

			setResize( getUserSetting('upload_resize', false) );


 ```




![upload.png](https://qiita-image-store.s3.amazonaws.com/0/60924/d032a592-9d83-1dc9-043a-28281c31b438.png)


※s3にはフォルダというものがなく、”hoge1/hoge2/hoge.txt”という文字列をcreate_object($bucket,$filename,$opt)の$filenameに入れることで、awsコンソール上ではフォルダのように階層的に見えています。
[create_object()](http://docs.aws.amazon.com/AWSSDKforPHP/latest/index.html#m=AmazonS3/create_object)

--



![hoge.png](https://qiita-image-store.s3.amazonaws.com/0/60924/cb147489-5612-ca64-aa2b-950bec60e863.png)

--

###まぁ、、S3にアップロードするためのWordPressプラグイン沢山ございますよね。。。。・


##さいごに
[CYBIRD エンジニア Advent Calendar](http://qiita.com/advent-calendar/2014/cybird)
明日は6日目の[繁田くん](http://qiita.com/cy-tomohiro-takahashi)です！
よろしくおねがしまーす！