WordPressのマルチサイトで、子ブログでアップロードしたファイルの「実際のファイルパス」を取得する関数を書いた

WordPressのマルチサイトを利用して子ブログを作った場合、
子ブログでアップロードしたメディアファイルは、
全て /wp-content/blogs.dir/{blog_id}/{year}/{month}/{file_name} に保存されるようになっています。

しかしながら、実際にアップロードしたファイルのURLを取得すると、
/{account_name}/files/{year}/{month}/{file_name} というURLが帰ってきます。
これは、マルチサイト用の .htaccess にURLの書き換え処理が記載されているためです。

# uploaded files
RewriteRule ^([_0-9a-zA-Z-]+/)?files/(.+) wp-includes/ms-files.php?file=$2 [L]

このURLに直接アクセスすればファイルは表示されますし、通常の利用上では全く問題はありません。

しかしながら、サムネイルを生成する際に非常に便利なライブラリである TimThumbなどを利用する際に、この書き換えられたURLが問題になります。

TimThumbは、与えられたURLから実際のファイルパスを計算し、ファイルを読み込もうとします。

しかし、この与えられたURLは .htaccess により書き換えられたダミーのURLのため、実際にこの場所にはファイルは存在しません。

そのため、書き換えられる前のURLが必要になります。

関数作った

下記のような関数を作ってみました。

function ms_calc_media_url($blog_id, $media_url)
{
	global $wpdb;

	switch_to_blog($wpdb->siteid);
	$url = preg_replace('|^' . get_blog_option($blog_id, 'siteurl') . '/(files/[\d]{4}/[\d]{2}/.+)$|', get_bloginfo('url') . '/wp-content/blogs.dir/' . $blog_id . '/$1', $media_url);
	restore_current_blog();

	return $url;
}

$blog_id に当該のファイルをアップロードした子ブログのIDを指定して、$media_url にファイルのURLを与えれば、書き換えられる前のURLを計算して出力します。

この関数を使うことで、問題無くTimThumbなどのライブラリを活用できます。