読者です 読者をやめる 読者になる 読者になる

WordPress 年齢認証プラグイン

WordPressでページやブログ記事に貼ったエロ画像を、認証しないと見えなくするプラグインを作ってみた。
まず成人向けの画像や動画を含む記事を書くときに、カスタムフィールドで"R18"という項目を作り、"true"という値をセットしておく。まあ、いちいちタイプするのは大変なので、このへんは適当にカスタムフィールドを使いやすくするプラグインを別途使うとよい。僕はEasy Castom Fieldsを利用している。でもって、このフィールドの値を読み取って、"true"ならその記事に含まれる画像を代替画像に置き換える。

未認証だとこう。


画像または下のリンクをクリックすると認証ページに飛ぶ。ここでYESをクリックすれば


こうなる。

プラグインファイル(adult_filter.php)は以下のような感じ

<?php
/*
Plugin Name: adult_filter
Plugin URI: 
Description: 
Version: 0.1
Author: Juan Gotoh
Author URI: http://www.juangotoh.net
*/

add_filter('the_content','juan_adult_filter',12);

function juan_adult_filter($content) {
	$result = juan_do_filter($content);
	return $result;
}

function juan_do_filter($content) {
	$result=$content;
	$c = explode(",",$_COOKIE["adult"]);
	if ($c[0] !="true"){
		$r18=get_post_custom_values("R18");
		$r18image=WP_PLUGIN_URL . "/adult_filter/R18.png";
		$path=WP_PLUGIN_URL . "/adult_filter/verification1.php";
		if ($r18[0] =="true"){
			$reg=array();
			$rep=array();
			$reg[]='/<a href=[\"|\']([^>]*?><img)/i';
			$rep[]="<a href=\"$path\"><img";
			
			$reg[]='/<img(.*?)src=[\"|\']([^>]*?\.)(jpg|gif|png)(.*?>)/i';
			$rep[]="<a href=\"$path\"><img $1src=\"$r18image$4</a>";
			
			$reg[]='/<object (.*?)width=.([0-9]+)(.*?)height=.([0-9]+)(.*?)\/object>/i';
			$rep[]="<a href=\"$path\"><img src=\"$r18image\" width=\"$2\" height=\"$4\"></a>";
			$str=preg_replace($reg,$rep,$content,-1,$count);
			if ($count >0){
				$str.="<p><a href='$path'>Image(s) are omitted be cause it is for adult only.<br />成人向け画像は隠されています<br />内容を見る<br /></a></p>";
			}
			$result= $str;
		}
	}
	return $result;
}
?>

クッキーに"adult"という項目があるかどうかチェックし、なかったら、画像を隠す。ムダに関数が二段階になってるのは試行錯誤の残滓なので気にしないで欲しい。あと、正規表現がメタメタなのも。

なお、add_filter()の第三引数(フィルタの優先度)は通常10までで、デフォルトだと10になるようだが、[gallery]ショートコードの展開が優先度11で行われるらしいので、デフォルトだとギャラリーページは展開前のショートコードだけになっちゃって、フィルタされないでしまう。したがってここで11より大きい数字を入れてやる必要がある。

隠すだけでは永遠にみられないので、認証ページに飛んで認証させるようにしている。
認証ページ(verification1.php)は以下のような物。

<html>
<head>
<title>Juan Gotoh Visual Workshop 年齢認証</title>
<style type="text/css">
<!--
h1 {
	text-align: center;
	background-color: #772211;
	color: white;
}

p {
	text-align: center;
	color: black;
}
p.question {
	text-align: center;
	font-weight: bold;
	font-size: large;
	color: #661111;
-->
</style>
</head>
<body>
<h1>年齢認証 - Age verification</h1>
<p>あなたは18歳以上ですか?</p>
<p>Are you over 18 and want to see adult materials in this site?</p>
<p class=question>
<?php
	$ref=$_SERVER['HTTP_REFERER'];
	$url="verification2.php";
	if ($ref){
		$encode=urlencode($ref);
		$url.="?ref=$ref";
	}
echo "<a href=$url>YES</a> ";
echo "<a href='$ref'>NO</a>";
?>
</p>
</body>
</html>

ここではリファラ情報から飛んできたページを保存し、18歳以上かどうかの質問にYESと答えたら、次のページに渡している。NOと答えたら飛んできたページに戻る。
あ、いま気づいたけど、リファラ送信を切ってたらまずいな…あとで直しておこう。修正しました。

次のページ(verification2.php)は認証情報をクッキーに書き込む。以下のような感じ。

<?php>
$ref=$_GET['ref'];
if (!$ref){
	$ref="http://www.mysite.mydomain/"; // <-ここはリファラがなかった場合の戻り先、ブログトップを入れておく。
}
$ref = urldecode($ref);
$timeout=time()+60*60*24*30;
setcookie("adult","true",$timeout,"/");
header("Location: $ref");
?>

このページはクッキーを書き込んだら直ちに元のページにリダイレクトするようになっているので、画面には何も表示されない。

これらの三つのファイルと、表示されない画像の代わりになる画像ファイル。この場合はR18.png を一つのフォルダに入れて、wp-contents/pluginsの下に置いてから、管理画面でadult_filterを使用開始すれば動作する。

<a href="ほげほげ"><img src="なんちゃら.jpg" /></a>

という風なリンク付の画像と

<img src="なんちゃら.jpg" />

みたいな画像単体と

<object embed ふにゃふにゃ width="xxx" height="yyy" > </object>

みたいな埋め込み動画をすべて置き換える。

あくまで個人的に作成したプラグインなので、国際化とか一切無視。そんなに需要もないだろうしね。もし改良するなら、専用カスタムフィールド用のUIを作っちゃうとか、HTML5のvideoタグにも対応するとか、まあいろいろ考えられる。あと、メディアページに直に飛ばれちゃうと隠しようがない(メディアにはカスタムフィールド設定できないので)とかいう問題もある。