/usr/local/CPAN/FormValidator-LazyWay/FormValidator/LazyWay/Message.pm
package FormValidator::LazyWay::Message;
use strict;
use warnings;
use Data::Dumper;
use Carp;
use UNIVERSAL::require;
use base 'FormValidator::LazyWay::Rule';
__PACKAGE__->mk_accessors(qw/rule config alias lang langs rule_message base_message labels/);
sub new {
my $class = shift;
my $args;
if ( ref $_[0] eq 'HASH' ) {
$args = shift;
}
else {
my %args = @_;
$args = \%args;
}
croak 'you must set config' unless exists $args->{config};
croak 'you must set rule' unless exists $args->{rule};
my $self = bless $args, $class;
$self->_set_lang();
$self->{labels} = $self->_get_label();
$self->{rule_message}
= $self->_finalize_rule_message( $self->_load_rule_message() );
return $self;
}
sub _get_label {
my $self = shift;
my $config = $self->{config}{labels} || {};
my $labels = {};
foreach my $lang ( keys %{$config} ) {
for my $field ( keys %{ $config->{$lang} } ) {
$labels->{$lang}{$field} = $config->{$lang}{$field};
}
}
return $labels;
}
sub _finalize_rule_message {
my $self = shift;
my $rule_message = shift;
my $message_storage = {};
foreach my $lang ( @{ $self->langs } ) {
foreach my $level ( keys %{ $self->rule->setting } ) {
foreach my $field ( keys %{ $self->rule->setting->{$level} } )
{
for my $item (
@{ $self->rule->setting->{$level}{$field} } )
{
my $message = $rule_message->{$lang}{ $item->{label} };
foreach my $key ( keys %{ $item->{args} } ) {
my $regexp = '\$_\[' . $key . '\]';
my $value = $item->{args}{$key};
$message =~ s/$regexp/$value/g;
}
$message_storage->{$lang}{$level}{$field}
{ $item->{label} } = $message;
}
}
}
}
return $message_storage;
}
sub get {
my $self = shift;
my $params = shift;
return $self->rule_message->{ $params->{lang} }{ $params->{level} }
{ $params->{field} }{ $params->{label} };
}
sub _set_lang {
my $self = shift;
$self->{lang} = $self->config->{lang} || 'en';
$self->{langs} = $self->config->{langs} || [ $self->lang ];
for my $lang ( @{ $self->{langs} } ) {
my $pkg = __PACKAGE__ . '::' . uc $lang;
$pkg->require;
$self->{base_message}{$lang} = {
invalid => $self->config->{messages}{$lang}{invalid}
|| $pkg->invalid(),
missing => $self->config->{messages}{$lang}{missing}
|| $pkg->missing(),
};
}
}
sub _load_rule_message {
my $self = shift;
my @subs = (
sub { $self->_load_from_config(@_) },
sub { $self->_load_from_rule(@_) },
sub { $self->_loading_error(@_) },
);
my %message = ();
LANG:
for my $lang ( @{ $self->langs } ) {
$self->_loading_modules($lang);
LABEL:
foreach my $label ( keys %{ $self->rule->labels } ) {
MESSAGE:
for my $sub (@subs) {
my $message
= $sub->( $lang, $label, $self->rule->labels->{$label} );
$message{$lang}{$label} = $message;
last MESSAGE if $message;
}
}
}
return \%message;
}
sub _loading_modules {
my $self = shift;
my $lang = shift;
for my $module ( @{ $self->rule->modules } ) {
my $package = $module . '::' . uc $lang;
$package->require;
}
}
sub _loading_error {
my $self = shift;
my $lang = shift;
my $label = shift;
croak sprintf( "You need to have rule message for lang:%s label:%s",
$lang, $label );
return;
}
sub _load_from_config {
my $self = shift;
my $lang = shift;
my $label = shift;
my $config = $self->config->{messages};
return $config->{$lang}{rule}{$label} if $config->{$lang}{rule}{$label};
my $alias = $self->rule->labels->{$label}{alias};
return unless $alias;
return $config->{$lang}{rule}{$alias} if $config->{$lang}{rule}{$alias};
return;
}
sub _load_from_rule {
my $self = shift;
my $lang = shift;
my $label = shift;
my $package_info = shift;
my $package = $package_info->{package} . '::' . uc $lang;
my $method = $package . '::' . $package_info->{method};
my $message;
no strict 'refs';
eval { $message = $method->(); };
return $message;
}
1;