view Lib/IMPL/Web/Handler/LocaleHandler.pm @ 393:69a1f1508696

minor security refactoring
author cin
date Fri, 14 Feb 2014 16:41:12 +0400
parents eff7f75a4408
children 212cc86e470b
line wrap: on
line source

package IMPL::Web::Handler::LocaleHandler;
use strict;

use IMPL::Const qw(:prop);
use IMPL::declare {
	require => {
		Resources => 'IMPL::Resources'
	},
	base => [
		'IMPL::Object' => undef,
		'IMPL::Object::Autofill' => '@_',
		'IMPL::Object::Serializable' => undef
	],
	props => [
		locales => PROP_RO | PROP_LIST,
		default => PROP_RO,
		cookie  => PROP_RO
	]
};

sub Invoke {
    my ($this,$action,$nextHandler) = @_;
    
    my $locale;
    
    if ($this->cookie and my $cookie = $action->cookie($this->cookie)) {
    	($locale) = grep /^$cookie/i, $this->locales;
    }
    
    unless($locale) {
	    my @matches;
	    
	    my $best = [$this->default,0];
	    
	    if(my $header = $action->header('Accept-Language')) {
	    	foreach my $part (split(/\s*,\s*/, $header)) {
	    		my ($lang,$quality) = ($part =~ /([a-z]+(?:\-[a-z]+)*)(?:\s*;\s*q=(0\.[\d]+|1))?/i );
	    		
	    		$quality ||=1;
	    		
	    		foreach my $tag ($this->locales) {
	    			if ( $tag =~ m/^$lang/i ) {
	    				push @matches, [$tag,$quality];
	    			}
	    		}
	    	}
	    	
	    	foreach my $match (@matches) {
	    		if ($match->[1] > $best->[1]) {
	    			$best = $match;
	    		}
	    	}
	    	
	    }
	    
	    $locale = $best->[0];
    }
    
    Resources->SetLocale($locale) if $locale;
    
    return $nextHandler->($action);
}

1;

__END__

=pod

=head1 NAME

C<IMPL::Web::Handler::LocaleHandler> - handles locale for the request

=head1 SYNOPSIS

=begin code xml

	<handlers type="ARRAY">
		<item type="IMPL::Web::Handler::LocaleHandler">
			<locales type="ARRAY">
				<item>en-US</item>
				<item>ru-RU</item>
			</locales>
			<default>en-US</default>
			<cookie>lang</cookie>
		</item>
	</handlers>

=end code xml

=cut