Contact Form 7 で独自のフォームタグ作成（今年から●年後までが選択肢になるセレクトボックス）

WordPressでお問い合わせフォームを作成するプラグイン「[Contact Form 7](http://contactform7.com/ja/)」
大体のフォーム部品は設定できるのですが、すこしだけ便利にしたい。というときの備忘録

# 今年から●年後までが、選択肢として、自動的に表示されるセレクトボックス
セレクトボックスは簡単につくれますが、その選択肢を動的に生成したいとき。
何かの年月日の予約だったり、あとはリクルートサイトなどで問い合わせするときに卒業予定年度を聞いたりとか、そういうときに、過去の年度は必要ない場合がありますよね。
そんなときなどに、今年度から１０年後までを選択するようなセレクトボックスを表示したいとき、2016,2017,2018,2019・・・・とセレクトボックスを作っておいても、２０１７年になったら、２０１６年が余計な選択肢になってしまいます。また、先の話にはなりますが、そのまま修正しなければ、いつかは選択肢が過去の年度ばかりになってしまいます。
毎年メンテナンスして選択肢を変えれば済むことなんですが、忘れてしまったりとかもあるかもしれません。

で、選択肢を動的に生成するためのフォーム部品を作成してみます。

## ショートコードのサンプル

なるべくContact Form ７のショートコードに近くなるようにつくりました。

```text:shortcode
[from_this_year year until:5 class:yearselect include_blank]
[from_this_year* year until:5 class:yearselect include_blank] //※必須の場合
```
[from_thie_year 部品名 属性値]
というショートコードで表示します。（属性は下記）

`[from_this_year year]`
で最低限動作します。
`[from_this_year* year]`
ってすると必須項目になります。

##属性

- **until** 数字を設定すると、今年から●年後までをセレクトボックスの選択値として表示できます。（デフォルトは１０年後）
- **class** クラス名をつけます。（任意）
- **id** id名を設定します。（任意）
- **include_blank** 設定すると選択肢の１行目に空白の値（「選択してください」というテキスト）を設定します。（任意）

##functions.phpへの実装

functions.phpに以下を書くことで動作します。細かい部分は適宜変更してください。

```php:functions.php
//今年から●年を表示するセレクトボックス

wpcf7_add_shortcode('from_this_year','make_from_this_year',true);
wpcf7_add_shortcode('from_this_year*','make_from_this_year',true);
function make_from_this_year($tag){
  //デフォルト
  $default=array(
    'until'=>10,
  );
  //今年（開始）
  $this_year=intval(date_i18n('Y'));
  // オプション値
  $t = new WPCF7_Shortcode($tag);
  //何年後まで
  $until=$t->get_option('until','int',true);//何年後か
  if($until===false)$until=$default['until'];

  // html組み立て
  $class=($class=$t->get_option('class','',true))?' class="'.esc_attr($class).'"':'';
  $id=($id=$t->get_option('id','',true))?' id="'.esc_attr($id).'"':'';

  $result='<span class="wpcf7-form-control-wrap '.esc_attr($tag['name']).'">';
  $result.='<select name="'.esc_attr($tag['name']).'"'.$class.$id.'>';
  if($t->has_option('include_blank'))$result.='<option value="">選択してください</option>';//先頭に空白値
  for($i=0;$i<$until;$i++){
    $year=$this_year+$i;
    $result.='<option value="'.$year.'">'.$year.'</option>';
  }
  $result.='</select></span>';

  return $result;

}

// バリデート
add_filter( 'wpcf7_validate_from_this_year*', 'wpcf7_custom_from_this_year_validation', 10, 2 );
function wpcf7_custom_from_this_year_validation( $result, $tag ) {
  $type = $tag['type'];
  $name = $tag['name'];
  if($type=='from_this_year' || $type=='from_this_year*'){
    $year =isset($_POST[$name])?trim($_POST[$name]):'';
    if (!$year) {
      if (method_exists($result, 'invalidate')) {
        $result->invalidate($tag,'選択してください');//エラーメッセージ
      }else{
        $result['valid'] = false;
        $result['reason'] = array($name=>'選択してください');//エラーメッセージ
      }
    }
  }
  return $result;
}

```

という感じです。

これで、２０１６年中は、２０１６〜２０２0　とかの選択肢。２０１７年になったら２０１７〜２０21とかの選択肢が自動的に表示されるはず。
<img width="265" alt="スクリーンショット 2016-10-27 14.28.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/73833/a58d7692-006a-8cc0-78c1-c9a6611e4904.png">

あまり使う局面がないコードかもしれませんが、これを応用することで、Contact Form 7がいろいろとカスタマイズしやすくなると思ったので備忘録。

あと、バリデートは最低限なので、ほんとはもっとちゃんとしたほうがいいかもです。
多分、プラグインとかでこういうのある気がするけど・・・

##参考にさせていただいたサイト
https://wordpress.org/support/topic/validate-custom-shortcode-field/
http://hookr.io/classes/wpcf7_shortcode/