WordPressプラグイン MW WP Form に Throws SPAM Away を使ったバリデーションを設定画面から設定する

前回、「WordPressプラグインThrows SPAM Awayを使ってMW WP FormにNGワード指定などのバリデーションを追加する方法」というタイトルでMW WP Formに「NGワード」のバリデーションを追加する方法を書きました。
http://qiita.com/gtijp/items/65bf0af75140fe2774a1

今回は、そもそも基本機能として「Throws SPAM Away」の設定を利用したバリデーションの設定が出来てしまうことを紹介します。

#WordPressプラグイン MW WP Form
https://wordpress.org/plugins/mw-wp-form/
今の私にはなくてはならないWordPress用メールフォームプラグインです。

#WordPressプラグイン Throws SPAM Away
https://wordpress.org/plugins/throws-spam-away/



##Throws SPAM Awayが有効化されてあればその設定で動きますパターン
Throws SPAM Awayのバージョン2.7.1から
プラグインの設定どおりにバリデーションを効かせることができるようになりました。

そのように挙動させるにはどうすればよいか・・・下のサンプルコードを 利用テーマの functions.phpに追記してください。

コード内の「mwform_validation_mw-wp-form-xxx」のxxxには利用するMW WP Formで作成したフォームIDを入れてください。

また、「不正IP」からのアクセスについてはコードの下記部分を適宜変更するようになります。
※不要な場合はこの分岐自体を削除してください。

```
			if ( ! $chk_ip ) {
				// 不正IPはそのままリダイレクト
				header( 'Location: http://www.yahoo.co.jp' );
				die;
			}

```
サンプルコードのままですとブラックリストに入っているIPからのアクセスをYahoo!さんに飛ばしてしまいます・・・。Yahoo!さんごめんなさい。

追記するサンプルコードはこちらです。

フォームの「content」という名前の項目に対してチェックをかけるコードになっています。
コード中の「mwform_validation_mw-wp-form-xxx」のxxxには MW WP Formで作成したフォームのIDを入れてください。

```functions.phpに追記
/**
 * my_validation_mw
 * @param object $Validation
 * @param array $data
 * $Validation::set_ruleの引数は name属性値, バリデーション名, オプション
 */
function my_validation_mw( $Validation, $data ) {
        // content というnameをつけたエレメントに対してバリデーションをかけるよ！っていう意味です。
	$Validation->set_rule( 'content', 'throws_spam_away' );

	return $Validation;
}
add_filter( 'mwform_validation_mw-wp-form-xxx', 'my_validation_mw', 10, 2 );

/**
 * my_validation_rule
 * @param array $validation_rules バリデーションルールオブジェクトの配列
 * @param string $key フォーム識別子
 */
function my_validation_rule( $validation_rules, $key ) {

    // 追加するバリデーションルールのオブジェクトは MW_Validation_Rule クラスを継承している必要があります。
    $validation_rules[throws_spam_away'] = new MW_WP_Form_Validation_Rule_Throws_Spam_Away( $key );
    return $validation_rules;
}
add_filter( 'mwform_validation_rules', 'my_validation_rule', 10, 2 );

class MW_WP_Form_Validation_Rule_Throws_Spam_Away extends MW_WP_Form_Abstract_Validation_Rule {

	/**
	 * バリデーションルール名を指定
	 * @var string
	 */
	protected $name = 'throws_spam_away';

	/**
	 * バリデーションチェック
	 *
	 * @param string $key name属性
	 * @param array $option
	 * @return string エラーメッセージ
	 */
	public function rule( $key, array $options = array() ) {
		include_once( WP_PLUGIN_DIR.'/throws-spam-away/throws_spam_away.class.php');

		$throwsSpamAway = new ThrowsSpamAway();

                // チェック用の条件を空にするとThrows SPAM Awayの設定で動く
		$args = array();
		$value = $this->Data->get( $key );
		$chk_result = $throwsSpamAway->validate_comment( "", $value, $args);
		if ( !MWF_Functions::is_empty( $value ) ) {

			// IPアドレスチェック
			$ip = $_SERVER['REMOTE_ADDR'];
			$chk_ip = $throwsSpamAway->ip_check( $ip );
			if ( ! $chk_ip ) {
				// 不正IPはそのままリダイレクト
				header( 'Location: http://www.yahoo.co.jp' );
				die;
			}

			$defaults = array();
			if ( !$chk_result ) {
				// エラータイプを取得
				$error_type = $throwsSpamAway->error_type;
				$message_str = "";
				/** 
					エラー種類
					'must_word'			必須キーワード
					'ng_word'			NGワード
					'url_count_over'	リンク数オーバー
					'not_japanese'		日本語不足
				*/
				switch ( $error_type ) {
					case "must_word":
						$message_str = "必須キーワードが入っていないため送信出来ません ";
						break;
					case "ng_word":
						$message_str = "NGワードが含まれているため送信できません ";
						break;
					case "url_count_over":
						$message_str = "リンクが多すぎます ";
						break;
					case "not_japanese":
						$message_str = "日本語が含まれないか日本語文字数が少ないため送信出来ません ";
						break;
					default:
						$message_str = "エラーが発生しました:".$error_type;
				}
				$defaults = array(
					'message' => $message_str
				);
			}
			$options = array_merge( $defaults, $options );
			return $options['message'];
		}
	}

	/**
	 * 設定パネルに追加
	 *
	 * @param numeric $key バリデーションルールセットの識別番号
	 * @param array $value バリデーションルールセットの内容
	 */
	public function admin( $key, $value ) {
	}
}
```

追加後はThrows SPAM Awayの設定で下記のチェックが効きます。
・日本語が存在しない場合エラー
・日本語の最低文字数（上記が有効の場合）
・リンクらしきURL文字列が存在する場合エラー
・リンクの許容数（上記が有効の場合）
・NGワードの設定（カンマ区切り）
・必須ワードの設定（カンマ区切り）

###Throws SPAM Awayの画面上は下のような箇所になります
![スクリーンショット 2015-11-20 4.16.24.png](https://qiita-image-store.s3.amazonaws.com/0/37489/fb683b16-38ea-66c0-7d01-cb16e0aa63ff.png)
※日本語が存在しない場合エラーにするか　＆　日本語文字の含有数（最低文字数）設定
![スクリーンショット 2015-11-20 4.20.05.png](https://qiita-image-store.s3.amazonaws.com/0/37489/de17956e-e4d0-cbcd-a539-52be50f3b3bf.png)
※URLらしき文字列が存在する場合エラーにするか ＆ 許容数設定
![スクリーンショット 2015-11-20 4.21.29.png](https://qiita-image-store.s3.amazonaws.com/0/37489/3a16e793-0d7f-5d8e-2fb8-3bb69ed1dc8c.png)
※NGワードの設定
![スクリーンショット 2015-11-20 4.22.22.png](https://qiita-image-store.s3.amazonaws.com/0/37489/50ce4615-8b5f-9f55-a9a2-a8598dc7a012.png)
※必須キーワードの設定

Throws SPAM Awayの方ではエラーメッセージも設定出来ますがサンプルコード上はそのエラーメッセージを利用しません。
下記の各メッセージを使うことでエラーメッセージもUIから入力できることになります。

```
$err_not_japanese_msg = get_option( 'tsa_error_message', "日本語文字列が入っていないか少ないです" );
$err_must_word_msg = get_option( 'tsa_must_key_error_message', "必須キーワードが入っていません" );
$err_ng_word_msg = get_option( 'tsa_ng_key_error_message',"NGワードは入っています" );
$err_url_count_over_msg = get_option( 'tsa_url_count_over_error_message', "URL文字列がいっぱいあります" );
```

※get_optionの第２引数は未指定時に代入されるデフォルト値となります。

ただし、コメントスパム対策用にも同様に適用されてしまうので注意してください。
実際には「スパムコメント」のエラー表示をしない（元の記事にもどってくる時間＝０）場合はメッセージが表示されることはなく関係ないです。

![スクリーンショット 2015-11-20 4.42.47.png](https://qiita-image-store.s3.amazonaws.com/0/37489/5b52455b-6c28-460d-5e61-2337167e8ad3.png)


最後に「Throws SPAM Away」の設定画面を利用しない場合での全部チェックパターンも掲載しておきます。
「必須キーワード」っていう特殊なチェックが入るとめんどくさいな・・・って個人的には思います。

ただ、例えば「投稿用コード」みたいなものを設定してあってそれを入れてくれなきゃフォーム送信できない場合はいいかな・・・って思います。
「自由欄」のような項目には「日本語」「URL制限」「NGワード」チェックを入れて
「パスコード」みたいな項目には「必須キーワード」チェックを入れるような活用が期待できると思います。

##全部乗せパターン

フォームの「content」という名前の項目に対してチェックをかけるコードになっています。
コード中の「mwform_validation_mw-wp-form-xxx」のxxxには MW WP Formで作成したフォームのIDを入れてください。

```functions.php
/**
 * my_validation_mw
 * @param object $Validation
 * @param array $data
 * $Validation::set_ruleの引数は name属性値, バリデーション名, オプション
 */
function my_validation_mw( $Validation, $data ) {

	$Validation->set_rule( 'content', 'throws_spam_away' );

	return $Validation;
}
add_filter( 'mwform_validation_mw-wp-form-xxx', 'my_validation_mw', 10, 2 );

/**
 * my_validation_rule
 * @param array $validation_rules バリデーションルールオブジェクトの配列
 * @param string $key フォーム識別子
 */
function my_validation_rule( $validation_rules, $key ) {

    // 追加するバリデーションルールのオブジェクトは MW_Validation_Rule クラスを継承している必要があります。
    $validation_rules['throws_spam_away'] = new MW_WP_Form_Validation_Rule_Throws_Spam_Away( $key );
    return $validation_rules;
}
add_filter( 'mwform_validation_rules', 'my_validation_rule', 10, 2 );

class MW_WP_Form_Validation_Rule_Throws_Spam_Away extends MW_WP_Form_Abstract_Validation_Rule {

	/**
	 * バリデーションルール名を指定
	 * @var string
	 */
	protected $name = 'throws_spam_away';

	/**
	 * バリデーションチェック
	 *
	 * @param string $key name属性
	 * @param array $option
	 * @return string エラーメッセージ
	 */
	public function rule( $key, array $options = array() ) {
		include_once( WP_PLUGIN_DIR.'/throws-spam-away/throws_spam_away.class.php');

		$throwsSpamAway = new ThrowsSpamAway();

		$args = array(
			  'post_id' => NULL,
			  'tsa_on_flg' => 1,	// 日本語利用していないとだめ！
			  'tsa_japanese_string_min_count' => 5,	// 日本語文字が５文字以上なければエラー
			  'tsa_ng_keywords'	=>	"私はたわし,馬鹿",	// NGキーワード指定のみ行う
			  'tsa_must_keywords'	=>	"マスト",	// 「マスト」という文字が入っていなければエラー
			  'tsa_url_count_check'	=>	1,			// リンクがあったらチェックする
			  'tsa_ok_url_count'	=>	2			// リンクが２個あったらエラー
			);
		$value = $this->Data->get( $key );
		$chk_result = $throwsSpamAway->validate_comment( "", $value, $args);
		if ( !MWF_Functions::is_empty( $value ) ) {

			// IPアドレスチェック
			$ip = $_SERVER['REMOTE_ADDR'];
			$chk_ip = $throwsSpamAway->ip_check( $ip );
			if ( ! $chk_ip ) {
				// 不正IPはそのままリダイレクト
				header( 'Location: http://www.yahoo.co.jp' );
				die;
			}

			$defaults = array();
			if ( !$chk_result ) {
				// エラータイプを取得
				$error_type = $throwsSpamAway->error_type;
				$message_str = "";
				/** 
					エラー種類
					'must_word'			必須キーワード
					'ng_word'			NGキーワード
					'url_count_over'	リンク数オーバー
					'not_japanese'		日本語不足
				*/
				switch ( $error_type ) {
					case "must_word":
						$message_str = "必須キーワードが入っていないため送信出来ません ";
						break;
					case "ng_word":
						$message_str = "NGキーワードが含まれているため送信できません ";
						break;
					case "url_count_over":
						$message_str = "リンクが多すぎます ";
						break;
					case "not_japanese":
						$message_str = "日本語が含まれないか日本語文字数が少ないため送信出来ません ";
						break;
					default:
						$message_str = "エラーが発生しました:".$error_type;
				}
				$defaults = array(
					'message' => $message_str
				);
			}
			$options = array_merge( $defaults, $options );
			return $options['message'];
		}
	}

	/**
	 * 設定パネルに追加
	 *
	 * @param numeric $key バリデーションルールセットの識別番号
	 * @param array $value バリデーションルールセットの内容
	 */
	public function admin( $key, $value ) {
	}
}
```

複数の項目にチェックをかける場合は
set_rule を増やし
項目チェックの内容をそれぞれ変えたい場合は
my_validation_rule の $validation_rules のバリエーションを増やし
チェッククラスを増やして対応すれば良いと思います。