FormValidator::Simple IN_ARRAY で、同名のパラメータが複数ある場合

例えば、下記のような HTML があったとする。

<input type="checkbox" name="hobby" value="music" /> Music
<input type="checkbox" name="hobby" value="movie" /> Movie
<input type="checkbox" name="hobby" value="game"  /> Game

この場合、SELECTED_AT_LEAST を使って、下記のようなチェックを行う事がある。

FormValidator::Simple->check($q => [ 
    hobby => ['NOT_BLANK', [qw(SELECTED_AT_LEAST 2)]],
]);

最低でも二つは選んでね。と。

で、個人的には、選択された項目が正しいかどうか IN_ARRAY とかでチェックしたいので、下記のように書けたら良いなぁと思う。

FormValidator::Simple->check($q => [ 
    hobby => ['NOT_BLANK', [qw(SELECTED_AT_LEAST 2)], [qw(IN_ARRAY music movie game)]],
]);

実際には、IN_ARRAY の source は下記のようになっており、同一名のパラメータが複数存在する場合には対応していない。

sub IN_ARRAY {
    my ($class, $params, $args) = @_;
    my $data = defined $params->[0] ? $params->[0] : '';
    return (List::MoreUtils::any { $_ eq $data } @$args) ? TRUE : FALSE;
}

check メソッドの複数パラメータ対応版メソッドを追加しようかと思ったが・・・

package FormValidator::Simple::MultiParams;

use strict;
use warnings;

use FormValidator::Simple::Constants;
use Scalar::Util qw(blessed);

sub import {
    no strict 'refs';
    *FormValidator::Simple::multi_params_check = sub {
        # do something
    };
}

1;

IN_ARRAY 以外の Validation で対応させる必要性を感じなかったので
下記のような Plugin を書いてみた。

package FormValidator::Simple::Plugin::MultiParamsInArray;

use strict;
use warnings;

use FormValidator::Simple::Exception;
use FormValidator::Simple::Constants;
use List::MoreUtils qw(any);

our $VERSION = '0.01';

sub MULTI_PARAMS_IN_ARRAY {
    my ($self, $params, $args) = @_;
    my $datas = ref $params->[0] eq 'ARRAY' ? $params->[0]
              : defined $params->[0]        ? [$params->[0]]
              : ['']
              ;

    for my $data (@$datas) {
        return FALSE if !any {$_ eq $data} @$args;
    }
    return TRUE;
}

1;

んー、ネーミングセンスない。