File Coverage

blib/lib/Captive/Portal/Role/I18N.pm
Criterion Covered Total %
statement 51 56 91.0
branch 8 16 50.0
condition 3 5 60.0
subroutine 7 7 100.0
pod 2 2 100.0
total 71 86 82.5


line stmt bran cond sub pod time code
1             package Captive::Portal::Role::I18N;
2              
3 6     6   51573 use strict;
  6         18  
  6         322  
4 6     6   39 use warnings;
  6         13  
  6         404  
5              
6             =head1 NAME
7              
8             Captive::Portal::Role::I18N - utils for internationalization
9              
10             =cut
11              
12             our $VERSION = '4.10';
13              
14 6     6   39 use Log::Log4perl qw(:easy);
  6         14  
  6         73  
15 6     6   5002 use Scalar::Util qw(looks_like_number);
  6         16  
  6         521  
16              
17 6     6   48 use Role::Basic;
  6         12  
  6         59  
18             requires qw(cfg);
19              
20             =head1 ROLES
21              
22             =over 4
23              
24             =item $capo->choose_language()
25              
26             Parses the HTTP header 'Accept-Language' and returns an appropriate language from the configured languages or the fallback language in config file.
27              
28             I18N_LANGUAGES => [ 'en', 'de', ],
29             I18N_FALLBACK_LANG => 'en',
30              
31             =cut
32              
33             sub choose_language {
34 7     7 1 22 my $self = shift;
35 7         25 my $query = $self->{CTX}{QUERY};
36              
37 7   100     163 my $http_accept_language = $query->http('HTTP_ACCEPT_LANGUAGE')
38             || '';
39 7         348 DEBUG("HTTP-Accept-Language is: $http_accept_language");
40              
41             ###
42             # parse the HTTP header
43             #
44             # Example header: de-de,de;q=0.8,en-us;q=0.5,en;q=0.3
45             #
46 7         74 my $default_quant = 1;
47 7         21 my %languages;
48              
49 7         33 foreach my $item ( split( /,/, $http_accept_language ) ) {
50 4         12 $item =~ s/\s//g; #strip spaces
51              
52 4         14 my ( $lang, $quant ) = split( /;q=/, $item );
53              
54             # don't use fine-granular language subtags for CaPo
55             # cutoff the language subtags: de-AT => de
56 4         9 $lang =~ s/-.*//;
57              
58             # skip silently the wildcard '*'
59 4 50       14 next if $lang eq '*';
60              
61             # parse error, silently skip this language item
62 4 50 33     18 next if defined $quant && ( not looks_like_number($quant) );
63              
64             # set the default language quantifier
65 4 50       10 unless ( defined $quant ) {
66              
67             # give the first one a quant of 1
68 4         7 $quant = $default_quant;
69              
70             # and the next without quantification .001 less
71 4         15 $default_quant -= 0.001;
72             }
73              
74             # first language entry
75 4 50       11 unless ( $languages{$lang} ) {
76 4         11 $languages{$lang} = $quant;
77 4         14 next;
78             }
79              
80             # override language entry with higher quant
81 0 0       0 if ( $quant > $languages{$lang} ) {
82 0         0 $languages{$lang} = $quant;
83 0         0 next;
84             }
85              
86             }
87              
88             # sort in descending quantification order
89 1         7 my @accept_languages_sorted =
90 7         44 sort { $languages{$b} <=> $languages{$a} } keys %languages;
91              
92 7         37 DEBUG( 'language prefered order is: '
93             . join( ' > ', @accept_languages_sorted ) );
94              
95 7         60 DEBUG( 'configured languages: '
96 7         50 . join( ' ', @{ $self->cfg->{I18N_LANGUAGES} } ) );
97              
98             # look for accepted language in configured languages
99 7         77 my $choosen_language;
100 7         24 foreach my $lang (@accept_languages_sorted) {
101 4 100       6 if ( grep m/\A\Q$lang\E\Z/, @{ $self->cfg->{I18N_LANGUAGES} } ) {
  4         24  
102 2         9 DEBUG "prefered language is: $lang";
103 2         25 return $lang;
104             }
105             }
106              
107 5         19 DEBUG 'take fallback language';
108 5         44 return $self->cfg->{I18N_FALLBACK_LANG};
109             }
110              
111             =item $capo->gettext($msg_nr)
112              
113             Poor mans gettext. Retrieve i18n system message from message catalog in config file. The default mesage catalog looks like:
114              
115             I18N_MSG_CATALOG => {
116             msg_001 => {
117             en => 'last session state was:',
118             de => 'Status der letzten Sitzung war:',
119             },
120              
121             msg_002 => {
122             en => 'username or password is missing',
123             de => 'Username oder Passwort fehlt',
124             },
125              
126             msg_003 => {
127             en => 'username or password is wrong',
128             de => 'Username oder Passwort ist falsch',
129             },
130              
131             msg_004 => {
132             en => 'successfull logout',
133             de => 'erfolgreich abgemeldet',
134             },
135              
136             msg_005 => {
137             en => 'admin_secret is wrong',
138             de => 'Admin-Passwort ist falsch',
139             },
140              
141             msg_006 => {
142             en => 'Idle-session reestablished due to valid cookie.',
143             de => 'Abgelaufene Sitzung durch gueltiges Cookie erneuert.',
144             },
145             },
146              
147             Add your own translation to the conig hash.
148              
149             =cut
150              
151             sub gettext {
152 1     1 1 2 my $self = shift;
153 1 50       6 my $text = shift
154             or LOGDIE 'missing param text';
155              
156 1         5 my $i18n_text =
157             $self->cfg->{I18N_MSG_CATALOG}{$text}{ $self->{CTX}{LANG} };
158              
159 1 50       9 unless ($i18n_text) {
160 0         0 ERROR "missing I18N text for '$text' in lang: $self->{CTX}{LANG}";
161 0         0 $i18n_text = "missing '$text' for lang '$self->{CTX}{LANG}'";
162             }
163              
164 1         6 return $i18n_text;
165             }
166              
167             1;
168              
169             =back
170              
171             =head1 AUTHOR
172              
173             Karl Gaissmaier, C<< >>
174              
175             =head1 LICENSE AND COPYRIGHT
176              
177             Copyright 2010-2013 Karl Gaissmaier, all rights reserved.
178              
179             This distribution is free software; you can redistribute it and/or modify it
180             under the terms of either:
181              
182             a) the GNU General Public License as published by the Free Software
183             Foundation; either version 2, or (at your option) any later version, or
184              
185             b) the Artistic License version 2.0.
186              
187             =cut
188              
189             # vim: sw=4
190