← Index
NYTProf Performance Profile   « block view • line view • sub view »
For /usr/local/src/github.com/foswiki/core/bin/view
  Run on Sun Dec 4 17:17:59 2011
Reported on Sun Dec 4 17:27:24 2011

Filename/usr/local/src/github.com/foswiki/core/lib/Foswiki/Form/FieldDefinition.pm
StatementsExecuted 667 statements in 5.49ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
28661.33ms1.66msFoswiki::Form::FieldDefinition::::newFoswiki::Form::FieldDefinition::new
1411958µs1.75msFoswiki::Form::FieldDefinition::::renderForDisplayFoswiki::Form::FieldDefinition::renderForDisplay
15491470µs470µsFoswiki::Form::FieldDefinition::::CORE:substFoswiki::Form::FieldDefinition::CORE:subst (opcode)
2822425µs425µsFoswiki::Form::FieldDefinition::::finishFoswiki::Form::FieldDefinition::finish
281192µs92µsFoswiki::Form::FieldDefinition::::CORE:substcontFoswiki::Form::FieldDefinition::CORE:substcont (opcode)
162128µs28µsFoswiki::Form::FieldDefinition::::CORE:matchFoswiki::Form::FieldDefinition::CORE:match (opcode)
11125µs33µsFoswiki::Form::FieldDefinition::::BEGIN@18Foswiki::Form::FieldDefinition::BEGIN@18
21122µs26µsFoswiki::Form::FieldDefinition::::isMandatoryFoswiki::Form::FieldDefinition::isMandatory
11118µs56µsFoswiki::Form::FieldDefinition::::BEGIN@20Foswiki::Form::FieldDefinition::BEGIN@20
11116µs34µsFoswiki::Form::FieldDefinition::::BEGIN@19Foswiki::Form::FieldDefinition::BEGIN@19
0000s0sFoswiki::Form::FieldDefinition::::cssClassesFoswiki::Form::FieldDefinition::cssClasses
0000s0sFoswiki::Form::FieldDefinition::::getDefaultValueFoswiki::Form::FieldDefinition::getDefaultValue
0000s0sFoswiki::Form::FieldDefinition::::isEditableFoswiki::Form::FieldDefinition::isEditable
0000s0sFoswiki::Form::FieldDefinition::::isMultiValuedFoswiki::Form::FieldDefinition::isMultiValued
0000s0sFoswiki::Form::FieldDefinition::::isTextMergeableFoswiki::Form::FieldDefinition::isTextMergeable
0000s0sFoswiki::Form::FieldDefinition::::populateMetaFromQueryDataFoswiki::Form::FieldDefinition::populateMetaFromQueryData
0000s0sFoswiki::Form::FieldDefinition::::renderForEditFoswiki::Form::FieldDefinition::renderForEdit
0000s0sFoswiki::Form::FieldDefinition::::renderHiddenFoswiki::Form::FieldDefinition::renderHidden
0000s0sFoswiki::Form::FieldDefinition::::stringifyFoswiki::Form::FieldDefinition::stringify
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1# See bottom of file for license and copyright information
2# base class for all form field types
3
4=begin TML
5
6---+ package Foswiki::Form::FieldDefinition
7
8Base class of all field definition classes.
9
10Type-specific classes are derived from this class to define specific
11per-type behaviours. This class also provides default behaviours for when
12a specific type cannot be loaded.
13
14=cut
15
16package Foswiki::Form::FieldDefinition;
17
18248µs240µs
# spent 33µs (25+8) within Foswiki::Form::FieldDefinition::BEGIN@18 which was called: # once (25µs+8µs) by Foswiki::Form::BEGIN@42 at line 18
use strict;
# spent 33µs making 1 call to Foswiki::Form::FieldDefinition::BEGIN@18 # spent 8µs making 1 call to strict::import
19246µs252µs
# spent 34µs (16+18) within Foswiki::Form::FieldDefinition::BEGIN@19 which was called: # once (16µs+18µs) by Foswiki::Form::BEGIN@42 at line 19
use warnings;
# spent 34µs making 1 call to Foswiki::Form::FieldDefinition::BEGIN@19 # spent 18µs making 1 call to warnings::import
2022.05ms294µs
# spent 56µs (18+38) within Foswiki::Form::FieldDefinition::BEGIN@20 which was called: # once (18µs+38µs) by Foswiki::Form::BEGIN@42 at line 20
use Assert;
# spent 56µs making 1 call to Foswiki::Form::FieldDefinition::BEGIN@20 # spent 38µs making 1 call to Assert::import
21
22=begin TML
23
24---++ ClassMethod new(%...)
25
26Construct a new FieldDefinition. Parameters are passed in a hash. See
27Form.pm for how it is called. Subclasses should pass @_ on to this class.
28
29=cut
30
31
# spent 1.66ms (1.33+325µs) within Foswiki::Form::FieldDefinition::new which was called 28 times, avg 59µs/call: # 14 times (698µs+164µs) by Foswiki::Form::createField at line 311 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Form.pm, avg 62µs/call # 6 times (255µs+71µs) by Foswiki::Form::Text::new at line 12 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Form/Text.pm, avg 54µs/call # 4 times (170µs+46µs) by Foswiki::Form::Select::new at line 13 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Form/Select.pm, avg 54µs/call # 2 times (92µs+20µs) by Foswiki::Form::Textboxlist::new at line 13 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Form/Textboxlist.pm, avg 56µs/call # once (63µs+12µs) by Foswiki::Form::Checkbox::new at line 12 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Form/Checkbox.pm # once (52µs+12µs) by Foswiki::Form::Radio::new at line 12 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Form/Radio.pm
sub new {
322848µs my $class = shift;
3328332µs my %attrs = @_;
3428141µs28109µs ASSERT( $attrs{session} ) if DEBUG;
# spent 109µs making 28 calls to Assert::ASSERTS_OFF, avg 4µs/call
35
362858µs $attrs{name} ||= '';
372843µs $attrs{attributes} ||= '';
382844µs $attrs{type} ||= ''; # default
392838µs $attrs{size} ||= '';
4028261µs28112µs $attrs{size} =~ s/^\s*//;
# spent 112µs making 28 calls to Foswiki::Form::FieldDefinition::CORE:subst, avg 4µs/call
4128233µs28104µs $attrs{size} =~ s/\s*$//;
# spent 104µs making 28 calls to Foswiki::Form::FieldDefinition::CORE:subst, avg 4µs/call
42
4328314µs return bless( \%attrs, $class );
44}
45
46=begin TML
47
48---++ ObjectMethod finish()
49Break circular references.
50
51=cut
52
53# Note to developers; please undef *all* fields in the object explicitly,
54# whether they are references or not. That way this method is "golden
55# documentation" of the live fields in the object.
56
# spent 425µs within Foswiki::Form::FieldDefinition::finish which was called 28 times, avg 15µs/call: # 20 times (295µs+0s) by Foswiki::Form::finish at line 151 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Form.pm, avg 15µs/call # 8 times (130µs+0s) by Foswiki::Form::ListFieldDefinition::finish at line 33 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Form/ListFieldDefinition.pm, avg 16µs/call
sub finish {
572842µs my $this = shift;
58
592890µs undef $this->{name};
602868µs undef $this->{attributes};
612864µs undef $this->{type};
622853µs undef $this->{size};
6328155µs undef $this->{session};
64}
65
66=begin TML
67
68---++ isEditable() -> $boolean
69
70Is the field type editable? Labels aren't, for example. Subclasses may need
71to redefine this.
72
73=cut
74
75sub isEditable { 1 }
76
77=begin TML
78
79---++ isMultiValued() -> $boolean
80
81Is the field type multi-valued (i.e. does it store multiple values)?
82Subclasses may need to redefine this.
83
84=cut
85
86sub isMultiValued { 0 }
87
88=begin TML
89
90---++ isTextMergeable() -> $boolean
91
92Is this field type mergeable using a conventional text merge?
93
94=cut
95
96# can't merge multi-valued fields (select+multi, checkbox)
97sub isTextMergeable { return !shift->isMultiValued() }
98
99=begin TML
100
101---++ isMandatory() -> $boolean
102
103Is this field mandatory (required)?
104
105=cut
106
107232µs24µs
# spent 26µs (22+4) within Foswiki::Form::FieldDefinition::isMandatory which was called 2 times, avg 13µs/call: # 2 times (22µs+4µs) by Foswiki::Form::_parseFormDefinition at line 277 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Form.pm, avg 13µs/call
sub isMandatory { return shift->{attributes} =~ /M/ }
# spent 4µs making 2 calls to Foswiki::Form::FieldDefinition::CORE:match, avg 2µs/call
108
109=begin TML
110
111---++ renderForEdit( $topicObject, $value ) -> ($col0html, $col1html)
112 =$topicObject= - the topic being edited
113Render the field for editing. Returns two chunks of HTML; the
114=$col0html= is appended to the HTML for the first column in the
115form table, and the =$col1html= is used as the content of the second column.
116
117=cut
118
119sub renderForEdit {
120 my ( $this, $topicObject, $value ) = @_;
121
122 # Treat like text, make it reasonably long, add a warning
123 return (
124 '<br /><span class="foswikiAlert">MISSING TYPE '
125 . $this->{type}
126 . '</span>',
127 CGI::textfield(
128 -class => $this->cssClasses('foswikiAlert foswikiInputField'),
129 -name => $this->{name},
130 -size => 80,
131 -value => $value
132 )
133 );
134}
135
136=begin TML
137
138---++ cssClasses(@classes) -> $classes
139Construct a list of the CSS classes for the form field. Adds additional
140class specifiers related to the attributes of the field e.g mandatory.
141Pass it a list of the other classnames you want on the field.
142
143=cut
144
145sub cssClasses {
146 my $this = shift;
147 if ( $this->isMandatory() ) {
148 push( @_, 'foswikiMandatory' );
149 }
150 return join( ' ', @_ );
151}
152
153=begin TML
154
155---++ getDefaultValue() -> $value
156Try and get a sensible default value for the field from the
157values stored in the form definition. The result should be
158a value string.
159
160Some subclasses may not support the definition of defaults in
161the form definition. In that case this method should return =undef=.
162
163=cut
164
165sub getDefaultValue {
166 my $this = shift;
167
168 my $value = $this->{value};
169 $value = '' unless defined $value; # allow 0 values
170
171 return $value;
172}
173
174=begin TML
175
176---++ renderHidden($meta) -> $html
177Render the form in =$meta= as a set of hidden fields.
178
179=cut
180
181sub renderHidden {
182 my ( $this, $meta ) = @_;
183
184 my $value;
185 if ( $this->{name} ) {
186 my $field = $meta->get( 'FIELD', $this->{name} );
187 $value = $field->{value};
188 }
189
190 my @values;
191
192 if ( defined($value) ) {
193 if ( $this->isMultiValued() ) {
194 push( @values, split( /\s*,\s*/, $value ) );
195 }
196 else {
197 push( @values, $value );
198 }
199 }
200 else {
201 $value = $this->getDefaultValue();
202 push( @values, $this->getDefaultValue() ) if $value;
203 }
204
205 return '' unless scalar(@values);
206
207 return CGI::hidden( -name => $this->{name}, -default => \@values );
208}
209
210=begin TML
211
212---++ populateMetaDataFromQuery( $query, $meta, $old ) -> ($bValid, $bPresent)
213
214Given a CGI =$query=, a =$meta= object, and an array of =$old= field entries,
215then populate the $meta with a row for this field definition, taking the
216content from the query if it's there, otherwise from $old or failing that,
217from the default defined for the type. Refuses to update mandatory fields
218that have an empty value.
219
220Return $bValid true if the value in $meta was updated (either from the
221query or from a default in the form.
222Return $bPresent true if a value was present in the query (even it was undef)
223
224=cut
225
226sub populateMetaFromQueryData {
227 my ( $this, $query, $meta, $old ) = @_;
228 my $value;
229 my $bPresent = 0;
230
231 return unless $this->{name};
232
233 my %names = map { $_ => 1 } $query->param;
234
235 if ( $names{ $this->{name} } ) {
236
237 # Field is present in the request
238 $bPresent = 1;
239 if ( $this->isMultiValued() ) {
240 my @values = $query->param( $this->{name} );
241
242 if ( scalar(@values) == 1 && defined $values[0] ) {
243 @values = split( /,|%2C/, $values[0] );
244 }
245 my %vset = ();
246 foreach my $val (@values) {
247 $val ||= '';
248 $val =~ s/^\s*//o;
249 $val =~ s/\s*$//o;
250
251 # skip empty values
252 $vset{$val} = ( defined $val && $val =~ /\S/ );
253 }
254 $value = '';
255 my $isValues = ( $this->{type} =~ /\+values/ );
256
257 foreach my $option ( @{ $this->getOptions() } ) {
258 $option =~ s/^.*?[^\\]=(.*)$/$1/ if $isValues;
259
260 # Maintain order of definition
261 if ( $vset{$option} ) {
262 $value .= ', ' if length($value);
263 $value .= $option;
264 }
265 }
266 }
267 else {
268
269 # Default the value to the empty string (undef would result
270 # in the old value being restored)
271 # Note: we test for 'defined' because value can also be 0 (zero)
272 $value = $query->param( $this->{name} );
273 $value = '' unless defined $value;
274 if ( $this->{session}->inContext('edit') ) {
275 $value = Foswiki::expandStandardEscapes($value);
276 }
277 }
278 }
279
280 # Find the old value of this field
281 my $preDef;
282 foreach my $item (@$old) {
283 if ( $item->{name} eq $this->{name} ) {
284 $preDef = $item;
285 last;
286 }
287 }
288 my $def;
289
290 if ( defined($value) ) {
291
292 # mandatory fields must have length > 0
293 if ( $this->isMandatory() && length($value) == 0 ) {
294 return ( 0, $bPresent );
295 }
296
297 # NOTE: title and name are stored in the topic so that it can be
298 # viewed without reading in the form definition
299 my $title = $this->{title};
300 if ( $this->{definingTopic} ) {
301 $title = '[[' . $this->{definingTopic} . '][' . $title . ']]';
302 }
303 $def = {
304 name => $this->{name},
305 title => $title,
306 value => $value,
307 attributes => $this->{attributes},
308 };
309 }
310 elsif ($preDef) {
311 $def = $preDef;
312 }
313 else {
314 return ( 0, $bPresent );
315 }
316
317 $meta->putKeyed( 'FIELD', $def ) if $def;
318
319 return ( 1, $bPresent );
320}
321
322=begin TML
323
324---++ ObjectMethod renderForDisplay($format, $attrs) -> $html
325
326Render the field for display, under the control of $attrs.
327
328The following vars in $format are expanded:
329 $title - title of the form field
330 $value - expanded to the *protected* value of the form field
331
332The value is protected by Foswiki::Render::protectFormFieldValue.
333
334=cut
335
336
# spent 1.75ms (958µs+790µs) within Foswiki::Form::FieldDefinition::renderForDisplay which was called 14 times, avg 125µs/call: # 14 times (958µs+790µs) by Foswiki::Form::renderForDisplay at line 613 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Form.pm, avg 125µs/call
sub renderForDisplay {
3371433µs my ( $this, $format, $value, $attrs ) = @_;
338
3391442µs if ( !$attrs->{showhidden} ) {
3401430µs my $fa = $this->{attributes} || '';
34114100µs1424µs if ( $fa =~ /H/ ) {
# spent 24µs making 14 calls to Foswiki::Form::FieldDefinition::CORE:match, avg 2µs/call
342 return '';
343 }
344 }
345
3461430µs require Foswiki::Render;
3471478µs14420µs $value = Foswiki::Render::protectFormFieldValue( $value, $attrs );
# spent 420µs making 14 calls to Foswiki::Render::protectFormFieldValue, avg 30µs/call
348
34914321µs42147µs $format =~ s/\$title/$this->{title}/g;
# spent 92µs making 28 calls to Foswiki::Form::FieldDefinition::CORE:substcont, avg 3µs/call # spent 55µs making 14 calls to Foswiki::Form::FieldDefinition::CORE:subst, avg 4µs/call
35014144µs1473µs $format =~ s/\$value/$value/g;
# spent 73µs making 14 calls to Foswiki::Form::FieldDefinition::CORE:subst, avg 5µs/call
3511487µs1428µs $format =~ s/\$name/$this->{name}/g;
# spent 28µs making 14 calls to Foswiki::Form::FieldDefinition::CORE:subst, avg 2µs/call
3521480µs1423µs $format =~ s/\$attributes/$this->{attributes}/g;
# spent 23µs making 14 calls to Foswiki::Form::FieldDefinition::CORE:subst, avg 2µs/call
3531482µs1425µs $format =~ s/\$type/$this->{type}/g;
# spent 25µs making 14 calls to Foswiki::Form::FieldDefinition::CORE:subst, avg 2µs/call
3541482µs1425µs $format =~ s/\$size/$this->{size}/g;
# spent 25µs making 14 calls to Foswiki::Form::FieldDefinition::CORE:subst, avg 2µs/call
3551429µs my $definingTopic = $this->{definingTopic} || 'FIELD';
3561482µs1424µs $format =~ s/\$definingTopic/$definingTopic/g;
# spent 24µs making 14 calls to Foswiki::Form::FieldDefinition::CORE:subst, avg 2µs/call
357
35814109µs return $format;
359}
360
361# Debug
362sub stringify {
363 my $this = shift;
364 my $s = '| '
365 . $this->{name} . ' | '
366 . $this->{type} . ' | '
367 . $this->{size} . ' | '
368 . $this->{attributes} . " |\n";
369 return $s;
370}
371
37214µs1;
373__END__
 
# spent 28µs within Foswiki::Form::FieldDefinition::CORE:match which was called 16 times, avg 2µs/call: # 14 times (24µs+0s) by Foswiki::Form::FieldDefinition::renderForDisplay at line 341, avg 2µs/call # 2 times (4µs+0s) by Foswiki::Form::FieldDefinition::isMandatory at line 107, avg 2µs/call
sub Foswiki::Form::FieldDefinition::CORE:match; # opcode
# spent 470µs within Foswiki::Form::FieldDefinition::CORE:subst which was called 154 times, avg 3µs/call: # 28 times (112µs+0s) by Foswiki::Form::FieldDefinition::new at line 40, avg 4µs/call # 28 times (104µs+0s) by Foswiki::Form::FieldDefinition::new at line 41, avg 4µs/call # 14 times (73µs+0s) by Foswiki::Form::FieldDefinition::renderForDisplay at line 350, avg 5µs/call # 14 times (55µs+0s) by Foswiki::Form::FieldDefinition::renderForDisplay at line 349, avg 4µs/call # 14 times (28µs+0s) by Foswiki::Form::FieldDefinition::renderForDisplay at line 351, avg 2µs/call # 14 times (25µs+0s) by Foswiki::Form::FieldDefinition::renderForDisplay at line 353, avg 2µs/call # 14 times (25µs+0s) by Foswiki::Form::FieldDefinition::renderForDisplay at line 354, avg 2µs/call # 14 times (24µs+0s) by Foswiki::Form::FieldDefinition::renderForDisplay at line 356, avg 2µs/call # 14 times (23µs+0s) by Foswiki::Form::FieldDefinition::renderForDisplay at line 352, avg 2µs/call
sub Foswiki::Form::FieldDefinition::CORE:subst; # opcode
# spent 92µs within Foswiki::Form::FieldDefinition::CORE:substcont which was called 28 times, avg 3µs/call: # 28 times (92µs+0s) by Foswiki::Form::FieldDefinition::renderForDisplay at line 349, avg 3µs/call
sub Foswiki::Form::FieldDefinition::CORE:substcont; # opcode