File Coverage

blib/lib/Mojolicious/Plugin/I18NUtils.pm
Criterion Covered Total %
statement 105 105 100.0
branch 13 16 81.2
condition 39 54 72.2
subroutine 19 19 100.0
pod 1 1 100.0
total 177 195 90.7


line stmt bran cond sub pod time code
1             package Mojolicious::Plugin::I18NUtils;
2              
3             # ABSTRACT: provide some helper functions for I18N
4 27     27   21054 use Mojo::Base 'Mojolicious::Plugin';
  27         75  
  27         281  
5 27     27   19879 use Time::Piece;
  27         193992  
  27         142  
6 27     27   15711 use CLDR::Number;
  27         2630711  
  27         1073  
7 27     27   12606 use HTTP::AcceptLanguage;
  27         61959  
  27         1026  
8              
9 27     27   13891 use Mojolicious::Plugin::I18NUtils::Locale;
  27         91  
  27         271  
10              
11             our $VERSION = '0.21';
12              
13             sub register {
14 27     27 1 23475 my ($self, $app, $config) = @_;
15              
16 27   100     233 my $parse_format = $config->{format} // '%Y-%m-%d %H:%M:%S';
17              
18 27         77 my %objects;
19              
20             $app->helper( browser_languages => sub {
21 133     133   45394 my $c = shift;
22              
23 133         432 my $lang = HTTP::AcceptLanguage->new( $c->req->headers->accept_language );
24 133         12209 return $lang->languages;
25 27         292 });
26              
27             $app->helper( datetime_loc => sub {
28 53     53   471260 my $c = shift;
29 53         136 my ($date, $lang) = @_;
30              
31 53   100     226 $lang //= ($c->browser_languages)[0];
32              
33 53 100       730 return '' if !defined $date;
34              
35 50         167 my $output_format = $self->_date_long( $lang );
36 50         151 my $formatted_date = $self->_translate( $date, $parse_format, $output_format );
37              
38 50         244 return $formatted_date;
39 27         4614 } );
40              
41             $app->helper( date_loc => sub {
42 63     63   557512 my $c = shift;
43 63         169 my ($date, $lang) = @_;
44              
45 63   100     303 $lang //= ($c->browser_languages)[0];
46              
47 63 100       830 return '' if !defined $date;
48              
49 60         217 my $output_format = $self->_date_short( $lang );
50 60         204 my $formatted_date = $self->_translate( $date, $parse_format, $output_format );
51              
52 60         310 return $formatted_date;
53 27         2873 } );
54              
55             $app->helper( date_from_to => sub {
56 12     12   108533 my $c = shift;
57 12         34 my ($date, $from, $to) = @_;
58              
59 12         58 my $in_format = $self->_date_short( $from );
60 12         40 my $out_format = $self->_date_short( $to );
61              
62 12 100       42 $out_format = '%Y-%m-%d' if lc $to eq 'iso';
63              
64 12         43 my $formatted_date = $self->_translate( $date, $in_format, $out_format );
65              
66 12         57 return $formatted_date;
67 27         2584 } );
68              
69             $app->helper( currency => sub {
70 30     30   294674 my ($c, $number, $locale, $currency, $opts) = @_;
71              
72 30   66     165 $locale //= ($c->browser_languages)[0];
73              
74 30   66     1110 $objects{cldr}->{$locale} ||= CLDR::Number->new( locale => $locale );
75 30   66     36865 $objects{cur}->{$locale} ||= $objects{cldr}->{$locale}->currency_formatter( currency_code => $currency );
76              
77 30         532492 my $cur_object = $objects{cur}->{$locale};
78              
79 30 50 66     160 if ( $opts && $opts->{cash} ) {
80 16         333 $cur_object->cash(1);
81             }
82              
83 30         5723 my $formatted = $cur_object->format( $number );
84 30         16749 $cur_object->cash(0);
85              
86 30         10484 return $formatted;
87 27         2395 } );
88              
89             $app->helper( decimal => sub {
90 18     18   170152 my ($c, $number, $locale) = @_;
91              
92 18   66     97 $locale //= ($c->browser_languages)[0];
93              
94 18   66     662 $objects{cldr}->{$locale} ||= CLDR::Number->new( locale => $locale );
95 18   66     19444 $objects{dec}->{$locale} ||= $objects{cldr}->{$locale}->decimal_formatter;
96              
97 18         231505 my $formatted = $objects{dec}->{$locale}->format( $number );
98 18         11940 return $formatted;
99 27         3437 } );
100              
101             $app->helper( range => sub {
102 27     27   264991 my ($c, $lower, $upper, $locale) = @_;
103              
104 27   66     114 $locale //= ($c->browser_languages)[0];
105              
106 27   66     904 $objects{cldr}->{$locale} ||= CLDR::Number->new( locale => $locale );
107 27   66     30215 $objects{dec}->{$locale} ||= $objects{cldr}->{$locale}->decimal_formatter;
108              
109 27         361422 my $formatted = $objects{dec}->{$locale}->range( $lower, $upper );
110 27         29386 return $formatted;
111 27         3063 } );
112              
113             $app->helper( at_least => sub {
114 54     54   474104 my ($c, $number, $locale) = @_;
115              
116 54   66     255 $locale //= ($c->browser_languages)[0];
117              
118 54   66     1162 $objects{cldr}->{$locale} ||= CLDR::Number->new( locale => $locale );
119 54   66     19300 $objects{dec}->{$locale} ||= $objects{cldr}->{$locale}->decimal_formatter;
120              
121 54         231623 my $formatted = $objects{dec}->{$locale}->at_least( $number );
122 54         33240 return $formatted;
123 27         2751 } );
124              
125             $app->helper( locale_obj => sub {
126 26     26   217953 my ( $c, $locale) = @_;
127              
128 26   66     106 $locale //= ($c->browser_languages)[0];
129              
130 26         353 return Mojolicious::Plugin::I18NUtils::Locale->new( locale => $locale );
131 27         3078 });
132             }
133              
134             sub _translate {
135 122     122   342 my ($self, $date, $in, $out) = @_;
136              
137 122 100       364 if ( length $date < 11 ) {
138 46         146 $date .= ' 00:00:00';
139             }
140              
141 122         236 my $out_date;
142              
143             {
144 122     12   209 local $SIG{__WARN__} = sub {};
  122         905  
145              
146 122 100       293 eval {
147 122         616 my $date_obj = Time::Piece->strptime( $date, $in );
148 114         8509 $out_date = $date_obj->strftime( $out );
149 114         6032 1;
150             } or $out_date = '';
151             }
152              
153 122         11808 return $out_date;
154             }
155              
156             sub _date_long {
157 50     50   114 my ($self, $lang) = @_;
158              
159 50 50       123 return "%d/%m/%Y %H:%M:%S" if !$lang;
160              
161 50         123 $lang = lc $lang;
162 50         152 $lang =~ s/-/_/g;
163              
164 50         358 state $formats = {
165             ar_sa => '%d.%m.%Y %H:%M:%S',
166             bg => '%d.%m.%Y %H:%M:%S',
167             ca => '%d.%m.%Y %H:%M:%S',
168             cs => '%d/%m/%Y %H:%M:%S',
169             da => '%d.%m.%Y %H:%M:%S',
170             de => '%d.%m.%Y %H:%M:%S',
171             el => '%d.%m.%Y %H:%M:%S',
172             en_ca => '%Y-%m-%d %H:%M:%S',
173             en_gb => '%d/%m/%Y %H:%M:%S',
174             en => '%m/%d/%Y %H:%M:%S',
175             es_co => '%d/%m/%Y - %H:%M:%S',
176             es_mx => '%d/%m/%Y - %H:%M:%S',
177             es => '%d/%m/%Y - %H:%M:%S',
178             et => '%d.%m.%Y %H:%M:%S',
179             fa => '%d.%m.%Y %H:%M:%S',
180             fi => '%d.%m.%Y %H:%M:%S',
181             fr_ca => '%d.%m.%Y %H:%M:%S',
182             fr => '%d.%m.%Y %H:%M:%S',
183             he => '%d/%m/%Y %H:%M:%S',
184             hi => '%d/%m/%Y - %H:%M:%S',
185             hr => '%d.%m.%Y %H:%M:%S',
186             hu => '%Y.%m.%d %H:%M:%S',
187             it => '%d/%m/%Y %H:%M:%S',
188             ja => '%Y/%m/%d %H:%M:%S',
189             lt => '%Y-%m-%d %H:%M:%S',
190             lv => '%d.%m.%Y %H:%M:%S',
191             ms => '%d.%m.%Y %H:%M:%S',
192             nb_no => '%d/%m %Y %H:%M:%S',
193             nl => '%d-%m-%Y %H:%M:%S',
194             pl => '%Y-%m-%d %H:%M:%S',
195             pt_br => '%d/%m/%Y %H:%M:%S',
196             pt => '%Y-%m-%d %H:%M:%S',
197             ru => '%d.%m.%Y %H:%M:%S',
198             sk_sk => '%d.%m.%Y %H:%M:%S',
199             sl => '%d.%m.%Y %H:%M:%S',
200             sr_cyrl => '%d.%m.%Y %H:%M:%S',
201             sr_latn => '%d.%m.%Y %H:%M:%S',
202             sv => '%d/%m %Y %H:%M:%S',
203             sw => '%m/%d/%Y %H:%M:%S',
204             tr => '%d.%m.%Y %H:%M:%S',
205             uk => '%m/%d/%Y %H:%M:%S',
206             vi_vn => '%d.%m.%Y %H:%M:%S',
207             zh_cn => '%Y.%m.%d %H:%M:%S',
208             zh_tw => '%Y.%m.%d %H:%M:%S',
209             };
210              
211 50   50     228 return $formats->{$lang} // '%d/%m/%Y %H:%M:%S';
212             }
213              
214             sub _date_short {
215 84     84   209 my ($self, $lang) = @_;
216              
217 84 50       219 return "%d/%m/%Y" if !$lang;
218              
219 84         196 $lang = lc $lang;
220 84         214 $lang =~ s/-/_/g;
221              
222 84         478 state $formats = {
223             ar_sa => '%d.%m.%Y',
224             bg => '%d.%m.%Y',
225             ca => '%d.%m.%Y',
226             cs => '%d/%m/%Y',
227             da => '%d.%m.%Y',
228             de => '%d.%m.%Y',
229             el => '%d.%m.%Y',
230             en_ca => '%Y-%m-%d',
231             en_gb => '%d/%m/%Y',
232             en => '%m/%d/%Y',
233             es_co => '%d/%m/%Y',
234             es_mx => '%d/%m/%Y',
235             es => '%d/%m/%Y',
236             et => '%d.%m.%Y',
237             fa => '%d.%m.%Y',
238             fi => '%d.%m.%Y',
239             fr_ca => '%d.%m.%Y',
240             fr => '%d.%m.%Y',
241             he => '%d/%m/%Y',
242             hi => '%d/%m/%Y',
243             hr => '%d.%m.%Y',
244             hu => '%Y.%m.%d',
245             it => '%d/%m/%Y',
246             ja => '%Y/%m/%d',
247             lt => '%Y-%m-%d',
248             lv => '%d.%m.%Y',
249             ms => '%d.%m.%Y',
250             nb_no => '%d.%m.%Y',
251             nl => '%d-%m-%Y',
252             pl => '%Y-%m-%d',
253             pt_br => '%d/%m/%Y',
254             pt => '%Y-%m-%d',
255             ru => '%d.%m.%Y',
256             sk_sk => '%d.%m.%Y',
257             sl => '%d.%m.%Y',
258             sr_cyrl => '%d.%m.%Y',
259             sr_latn => '%d.%m.%Y',
260             sv => '%Y.%m.%d',
261             sw => '%m/%d/%Y',
262             tr => '%d.%m.%Y',
263             uk => '%m/%d/%Y',
264             vi_vn => '%d.%m.%Y',
265             zh_cn => '%Y.%m.%d',
266             zh_tw => '%Y.%m.%d',
267             };
268              
269 84   100     383 return $formats->{$lang} // '%d/%m/%Y';
270             }
271              
272             1;
273              
274             __END__