Filename | /var/www/foswikidev/core/lib/Foswiki/Form/ListFieldDefinition.pm |
Statements | Executed 11 statements in 719µs |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
1 | 1 | 1 | 20µs | 34µs | BEGIN@14 | Foswiki::Form::ListFieldDefinition::
1 | 1 | 1 | 10µs | 14µs | BEGIN@15 | Foswiki::Form::ListFieldDefinition::
1 | 1 | 1 | 10µs | 36µs | BEGIN@16 | Foswiki::Form::ListFieldDefinition::
1 | 1 | 1 | 6µs | 6µs | BEGIN@21 | Foswiki::Form::ListFieldDefinition::
1 | 1 | 1 | 5µs | 5µs | BEGIN@18 | Foswiki::Form::ListFieldDefinition::
0 | 0 | 0 | 0s | 0s | finish | Foswiki::Form::ListFieldDefinition::
0 | 0 | 0 | 0s | 0s | getOptions | Foswiki::Form::ListFieldDefinition::
0 | 0 | 0 | 0s | 0s | isMultiValued | Foswiki::Form::ListFieldDefinition::
0 | 0 | 0 | 0s | 0s | isValueMapped | Foswiki::Form::ListFieldDefinition::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | # See bottom of file for license and copyright information | ||||
2 | |||||
3 | =begin TML | ||||
4 | |||||
5 | ---++ package Foswiki::Form::ListFieldDefinition | ||||
6 | Form field definitions that accept lists of values in the field definition. | ||||
7 | This is different to being multi-valued, which means the field type | ||||
8 | can *store* multiple values. | ||||
9 | |||||
10 | =cut | ||||
11 | |||||
12 | package Foswiki::Form::ListFieldDefinition; | ||||
13 | |||||
14 | 2 | 31µs | 2 | 48µs | # spent 34µs (20+14) within Foswiki::Form::ListFieldDefinition::BEGIN@14 which was called:
# once (20µs+14µs) by Foswiki::Form::BEGIN@43 at line 14 # spent 34µs making 1 call to Foswiki::Form::ListFieldDefinition::BEGIN@14
# spent 14µs making 1 call to strict::import |
15 | 2 | 25µs | 2 | 19µs | # spent 14µs (10+4) within Foswiki::Form::ListFieldDefinition::BEGIN@15 which was called:
# once (10µs+4µs) by Foswiki::Form::BEGIN@43 at line 15 # spent 14µs making 1 call to Foswiki::Form::ListFieldDefinition::BEGIN@15
# spent 4µs making 1 call to warnings::import |
16 | 2 | 27µs | 2 | 61µs | # spent 36µs (10+26) within Foswiki::Form::ListFieldDefinition::BEGIN@16 which was called:
# once (10µs+26µs) by Foswiki::Form::BEGIN@43 at line 16 # spent 36µs making 1 call to Foswiki::Form::ListFieldDefinition::BEGIN@16
# spent 26µs making 1 call to Exporter::import |
17 | |||||
18 | 2 | 57µs | 1 | 5µs | # spent 5µs within Foswiki::Form::ListFieldDefinition::BEGIN@18 which was called:
# once (5µs+0s) by Foswiki::Form::BEGIN@43 at line 18 # spent 5µs making 1 call to Foswiki::Form::ListFieldDefinition::BEGIN@18 |
19 | 1 | 12µs | our @ISA = ('Foswiki::Form::FieldDefinition'); | ||
20 | |||||
21 | # spent 6µs within Foswiki::Form::ListFieldDefinition::BEGIN@21 which was called:
# once (6µs+0s) by Foswiki::Form::BEGIN@43 at line 26 | ||||
22 | 1 | 6µs | if ( $Foswiki::cfg{UseLocale} ) { | ||
23 | require locale; | ||||
24 | import locale(); | ||||
25 | } | ||||
26 | 1 | 558µs | 1 | 6µs | } # spent 6µs making 1 call to Foswiki::Form::ListFieldDefinition::BEGIN@21 |
27 | |||||
28 | =begin TML | ||||
29 | |||||
30 | ---++ ObjectMethod finish() | ||||
31 | Break circular references. | ||||
32 | |||||
33 | =cut | ||||
34 | |||||
35 | # Note to developers; please undef *all* fields in the object explicitly, | ||||
36 | # whether they are references or not. That way this method is "golden | ||||
37 | # documentation" of the live fields in the object. | ||||
38 | sub finish { | ||||
39 | my $this = shift; | ||||
40 | $this->SUPER::finish(); | ||||
41 | undef $this->{_options}; | ||||
42 | undef $this->{_descriptions}; | ||||
43 | } | ||||
44 | |||||
45 | sub isMultiValued { return ( shift->{type} =~ m/\+multi/ ); } | ||||
46 | |||||
47 | sub isValueMapped { return ( shift->{type} =~ m/\+values/ ); } | ||||
48 | |||||
49 | # PROTECTED - parse the {value} and extract a list of options. | ||||
50 | # Done lazily to avoid repeated topic reads. | ||||
51 | sub getOptions { | ||||
52 | |||||
53 | # $web and $topic are where the form definition lives | ||||
54 | my $this = shift; | ||||
55 | |||||
56 | return $this->{_options} if $this->{_options}; | ||||
57 | |||||
58 | my @vals = (); | ||||
59 | my %descr = (); | ||||
60 | |||||
61 | @vals = split( /,/, $this->{value} ); | ||||
62 | |||||
63 | if ( !scalar(@vals) ) { | ||||
64 | my $topic = $this->{definingTopic} || $this->{name}; | ||||
65 | my $session = $this->{session}; | ||||
66 | |||||
67 | my ( $fieldWeb, $fieldTopic ) = | ||||
68 | $session->normalizeWebTopicName( $this->{web}, $topic ); | ||||
69 | |||||
70 | $fieldWeb = Foswiki::Sandbox::untaint( $fieldWeb, | ||||
71 | \&Foswiki::Sandbox::validateWebName ); | ||||
72 | $fieldTopic = Foswiki::Sandbox::untaint( $fieldTopic, | ||||
73 | \&Foswiki::Sandbox::validateTopicName ); | ||||
74 | |||||
75 | if ( $session->topicExists( $fieldWeb, $fieldTopic ) ) { | ||||
76 | |||||
77 | my $meta = Foswiki::Meta->load( $session, $fieldWeb, $fieldTopic ); | ||||
78 | if ( $meta->haveAccess('VIEW') ) { | ||||
79 | |||||
80 | # Process SEARCHES for Lists | ||||
81 | my $text = $meta->expandMacros( $meta->text() ); | ||||
82 | |||||
83 | # SMELL: yet another table parser | ||||
84 | my $inBlock = 0; | ||||
85 | foreach ( split( /\r?\n/, $text ) ) { | ||||
86 | if (/^\s*\|\s*\*Name\*\s*\|/) { | ||||
87 | $inBlock = 1; | ||||
88 | } | ||||
89 | elsif (/^\s*\|\s*([^|]*?)\s*\|(?:\s*([^|]*?)\s*\|)?/) { | ||||
90 | if ($inBlock) { | ||||
91 | push( @vals, TAINT($1) ); | ||||
92 | $descr{$1} = $2 if defined $2; | ||||
93 | } | ||||
94 | } | ||||
95 | else { | ||||
96 | $inBlock = 0; | ||||
97 | } | ||||
98 | } | ||||
99 | } | ||||
100 | } | ||||
101 | } | ||||
102 | @vals = map { $_ =~ s/^\s*(.*)\s*$/$1/; $_; } @vals; | ||||
103 | |||||
104 | $this->{_descriptions} = \%descr; | ||||
105 | |||||
106 | if ( $this->isValueMapped() ) { | ||||
107 | |||||
108 | # create a values map | ||||
109 | $this->{valueMap} = (); | ||||
110 | $this->{_options} = (); | ||||
111 | my $str; | ||||
112 | foreach my $val (@vals) { | ||||
113 | if ( $val =~ m/^(.*[^\\])*=(.*)$/ ) { | ||||
114 | $str = TAINT( $1 || '' ); # label | ||||
115 | # Copy the description to the real value | ||||
116 | my $descr = $this->{_descriptions}{$val}; | ||||
117 | $val = $2; | ||||
118 | $this->{_descriptions}{$val} = $descr; | ||||
119 | |||||
120 | # Unescape = - legacy! Entities should suffice | ||||
121 | $str =~ s/\\=/=/g; | ||||
122 | } | ||||
123 | else { | ||||
124 | # Label and value are the same | ||||
125 | $str = $val; | ||||
126 | } | ||||
127 | |||||
128 | # SMELL: when it was first coded, the subclasses of | ||||
129 | # ListFieldDefinition all did an urlDecode on labels in | ||||
130 | # parsed +values. This was undocumented, but presumably | ||||
131 | # was intended to protect any characters that might | ||||
132 | # interfere with the rendering of the form table, | ||||
133 | # but were desireable in the label. Quite why | ||||
134 | # URL encoding was chosen over the more obvious | ||||
135 | # entity encoding is obscure, as is the reasoning behind | ||||
136 | # applying the encoding to the label, but not the value. | ||||
137 | # For compatibility we retain this decoding step here. | ||||
138 | # It remains undocumented, and therefore a potential | ||||
139 | # gotcha for the unwary. | ||||
140 | $str =~ s/%([\da-f]{2})/chr(hex($1))/gei; | ||||
141 | |||||
142 | $this->{valueMap}{$val} = $str; | ||||
143 | push @{ $this->{_options} }, $val; | ||||
144 | } | ||||
145 | } | ||||
146 | else { | ||||
147 | $this->{_options} = \@vals; | ||||
148 | } | ||||
149 | |||||
150 | return $this->{_options}; | ||||
151 | } | ||||
152 | |||||
153 | 1 | 3µs | 1; | ||
154 | __END__ |