File Coverage

blib/lib/Rose/HTML/Form/Field/Set.pm
Criterion Covered Total %
statement 47 50 94.0
branch 20 24 83.3
condition n/a
subroutine 7 7 100.0
pod 3 3 100.0
total 77 84 91.6


line stmt bran cond sub pod time code
1              
2             use strict;
3 2     2   83271  
  2         13  
  2         60  
4             use Rose::HTML::Object::Errors qw(:set);
5 2     2   366  
  2         5  
  2         13  
6             use base 'Rose::HTML::Form::Field::TextArea';
7 2     2   10  
  2         14  
  2         990  
8             our $VERSION = '0.606';
9              
10             {
11             my($self, $list) = @_;
12              
13 16     16 1 29 my @list = $list ? @$list : (); # shallow copy
14              
15 16 100       47 return $self->input_value_filtered unless(ref $list eq 'ARRAY');
16              
17 16 100       40 return join(', ', map
18             {
19             if(/["\\\s,]/) # needs escaping
20             {
21 15 100       28 s/\\/\\\\/g; # escape backslashes
  60         113  
22             s/"/\\"/g; # escape double quotes
23 24         36 qq("$_") # double quote the whole thing
24 24         43 }
25 24         75 else { $_ }
26             }
27 36         89 @list);
28             }
29              
30             {
31             my($self, $value) = @_;
32              
33             return $value if(ref $value eq 'ARRAY');
34 17     17 1 28 return undef unless(defined $value);
35              
36 17 100       34 my @strings;
37 12 100       25  
38             # Extract comma- or whitespace-separated, possibly double-quoted strings
39 11         14 while(length $value)
40             {
41             $value =~ s/^(?:(?:\s*,\s*)+|\s+)//;
42 11         21  
43             last unless(length($value));
44 41         119  
45             if($value =~ s/^"((?:[^"\\]+|\\.)*)"//s)
46 41 100       71 {
47             my $string = $1;
48 37 100       134 # Interpolate backslash escapes
    100          
49             my $interpolated = $string;
50 17         34  
51             my $error;
52 17         21  
53             TRY:
54 17         19 {
55             local $@;
56             $interpolated =~ s/\\(.)/eval qq("\\$1")/ge;
57             $error = $@;
58 17         20 }
  17         20  
59 17         33  
  12         451  
60 17         29 if($error)
61             {
62             $self->add_error_id(SET_INVALID_QUOTED_STRING, { string => $string });
63 17 50       29 next;
64             }
65 0         0  
66 0         0 push(@strings, $interpolated);
67             }
68             elsif($value =~ s/^([^,"\s]+)//)
69 17         47 {
70             push(@strings, $1);
71             }
72             else
73 18         43 {
74             $self->error(SET_PARSE_ERROR, { context => (length($value) < 5) ? "...$value" :
75             '...' . substr($value, 0, 5) });
76             last;
77 2 50       13 }
78             }
79 2         5  
80             return \@strings;
81             }
82              
83 11         29 {
84             my($self) = shift;
85              
86             my $ok = $self->SUPER::validate(@_);
87             return $ok unless($ok);
88 1     1 1 2  
89             return 0 if($self->has_errors);
90 1         6 return 1;
91 1 50       4 }
92              
93 1 50       5 if(__PACKAGE__->localizer->auto_load_messages)
94 0           {
95             __PACKAGE__->localizer->load_all_messages;
96             }
97              
98             use utf8; # The __DATA__ section contains UTF-8 text
99              
100             1;
101              
102 2     2   15  
  2         4  
  2         19  
103             [% LOCALE en %]
104              
105             SET_INVALID_QUOTED_STRING = "Invalid quoted string: \"[string]\"" # Testing parser "
106             SET_PARSE_ERROR = "Could not parse input: parse error at \[[context]\]"
107              
108             [% LOCALE de %]
109              
110             SET_INVALID_QUOTED_STRING = "Ungültig gequoteter String: \"[string]\""
111             SET_PARSE_ERROR = "Konnte Eingabe nicht parsen: Fehler bei \[[context]\]"
112              
113             [% LOCALE fr %]
114              
115             SET_INVALID_QUOTED_STRING = "Texte entre guillemets invalide: \"[string]\""
116             SET_PARSE_ERROR = "Impossible d'évaluer la saisie : erreur à \[[context]\]"
117              
118             [% LOCALE bg %]
119              
120             SET_INVALID_QUOTED_STRING = "Нeвалиден низ в кавички: \"[string]\""
121             SET_PARSE_ERROR = "Невъзможна обработка на въведените данни: грешка при \[[context]\]"
122              
123             __END__
124              
125             =head1 NAME
126              
127             Rose::HTML::Form::Field::Set - Text area that accepts whitespace- or comma-separated strings.
128              
129             =head1 SYNOPSIS
130              
131             $field =
132             Rose::HTML::Form::Field::Set->new(
133             label => 'States',
134             name => 'states',
135             default => 'NY NJ NM');
136              
137             $vals = $field->internal_value;
138              
139             print $vals->[1]; # "NJ"
140              
141             $field->input_value('NY, NJ, "New Mexico"');
142              
143             $vals = $field->internal_value;
144              
145             print $vals->[3]; # "New Mexico"
146              
147             $field->input_value([ 'New York', 'New Jersey' ]);
148              
149             print $field->internal_value->[0]; # "New York"
150              
151             ...
152              
153             =head1 DESCRIPTION
154              
155             L<Rose::HTML::Form::Field::Set> is a subclass of L<Rose::HTML::Form::Field::TextArea> that accepts whitespace- or comma-separated strings. Its internal value is a reference to an array of strings, or undef if the input value could not be parsed.
156              
157             Strings with spaces, double quotes, backslashes, or commas must be double-quoted. Use a backslash character "\" to escape double-quotes within double-quoted strings. Backslashed escapes in double-quoted strings are interpolated according to Perl's rules.
158              
159             =head1 AUTHOR
160              
161             John C. Siracusa (siracusa@gmail.com)
162              
163             =head1 LICENSE
164              
165             Copyright (c) 2010 by John C. Siracusa. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.