← Index
NYTProf Performance Profile   « line view »
For ./view
  Run on Fri Jul 31 18:42:36 2015
Reported on Fri Jul 31 18:48:14 2015

Filename/var/www/foswikidev/core/lib/Foswiki/Plugins/RenderFormPlugin/Core.pm
StatementsExecuted 6 statements in 4.80ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
11122µs97µsFoswiki::Plugins::RenderFormPlugin::Core::::BEGIN@28Foswiki::Plugins::RenderFormPlugin::Core::BEGIN@28
11117µs41µsFoswiki::Plugins::RenderFormPlugin::Core::::BEGIN@1019Foswiki::Plugins::RenderFormPlugin::Core::BEGIN@1019
0000s0sFoswiki::Plugins::RenderFormPlugin::Core::::_createInvalidParamsMessageFoswiki::Plugins::RenderFormPlugin::Core::_createInvalidParamsMessage
0000s0sFoswiki::Plugins::RenderFormPlugin::Core::::_createJavaScriptFoswiki::Plugins::RenderFormPlugin::Core::_createJavaScript
0000s0sFoswiki::Plugins::RenderFormPlugin::Core::::_createMissingParamsMessageFoswiki::Plugins::RenderFormPlugin::Core::_createMissingParamsMessage
0000s0sFoswiki::Plugins::RenderFormPlugin::Core::::_createUnknownParamsMessageFoswiki::Plugins::RenderFormPlugin::Core::_createUnknownParamsMessage
0000s0sFoswiki::Plugins::RenderFormPlugin::Core::::_detectFormFoswiki::Plugins::RenderFormPlugin::Core::_detectForm
0000s0sFoswiki::Plugins::RenderFormPlugin::Core::::_dumpFoswiki::Plugins::RenderFormPlugin::Core::_dump
0000s0sFoswiki::Plugins::RenderFormPlugin::Core::::_encodeFoswiki::Plugins::RenderFormPlugin::Core::_encode
0000s0sFoswiki::Plugins::RenderFormPlugin::Core::::_getFoswiki::Plugins::RenderFormPlugin::Core::_get
0000s0sFoswiki::Plugins::RenderFormPlugin::Core::::_getFormFieldValuesFoswiki::Plugins::RenderFormPlugin::Core::_getFormFieldValues
0000s0sFoswiki::Plugins::RenderFormPlugin::Core::::_getSwitchButtonFoswiki::Plugins::RenderFormPlugin::Core::_getSwitchButton
0000s0sFoswiki::Plugins::RenderFormPlugin::Core::::_getWebAndTopicFoswiki::Plugins::RenderFormPlugin::Core::_getWebAndTopic
0000s0sFoswiki::Plugins::RenderFormPlugin::Core::::_initDefaultsFoswiki::Plugins::RenderFormPlugin::Core::_initDefaults
0000s0sFoswiki::Plugins::RenderFormPlugin::Core::::_initOptionsFoswiki::Plugins::RenderFormPlugin::Core::_initOptions
0000s0sFoswiki::Plugins::RenderFormPlugin::Core::::_intFoswiki::Plugins::RenderFormPlugin::Core::_int
0000s0sFoswiki::Plugins::RenderFormPlugin::Core::::_layoutTopicExistsFoswiki::Plugins::RenderFormPlugin::Core::_layoutTopicExists
0000s0sFoswiki::Plugins::RenderFormPlugin::Core::::_readDataFormsDefFoswiki::Plugins::RenderFormPlugin::Core::_readDataFormsDef
0000s0sFoswiki::Plugins::RenderFormPlugin::Core::::_readTopicFormDataFoswiki::Plugins::RenderFormPlugin::Core::_readTopicFormData
0000s0sFoswiki::Plugins::RenderFormPlugin::Core::::_readTopicTextFoswiki::Plugins::RenderFormPlugin::Core::_readTopicText
0000s0sFoswiki::Plugins::RenderFormPlugin::Core::::_readUserLayoutFoswiki::Plugins::RenderFormPlugin::Core::_readUserLayout
0000s0sFoswiki::Plugins::RenderFormPlugin::Core::::_renderButtonsFoswiki::Plugins::RenderFormPlugin::Core::_renderButtons
0000s0sFoswiki::Plugins::RenderFormPlugin::Core::::_renderFormFieldFoswiki::Plugins::RenderFormPlugin::Core::_renderFormField
0000s0sFoswiki::Plugins::RenderFormPlugin::Core::::_renderOptionsFoswiki::Plugins::RenderFormPlugin::Core::_renderOptions
0000s0sFoswiki::Plugins::RenderFormPlugin::Core::::_renderUserLayoutFoswiki::Plugins::RenderFormPlugin::Core::_renderUserLayout
0000s0sFoswiki::Plugins::RenderFormPlugin::Core::::_reorderDefsFoswiki::Plugins::RenderFormPlugin::Core::_reorderDefs
0000s0sFoswiki::Plugins::RenderFormPlugin::Core::::renderFoswiki::Plugins::RenderFormPlugin::Core::render
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1# RenderFormPlugin for Foswiki - The Free and Open Source Wiki, http://foswiki.org/
2#
3# Copyright (C) 2008 Daniel Rohde
4#
5# For licensing info read LICENSE file in the Foswiki root.
6# This program is free software; you can redistribute it and/or
7# modify it under the terms of the GNU General Public License
8# as published by the Free Software Foundation; either version 2
9# of the License, or (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details, published at
15# http://www.gnu.org/copyleft/gpl.html
16#
17# As per the GPL, removal of this notice is prohibited.
18
19package Foswiki::Plugins::RenderFormPlugin::Core;
20
21### todo:
22# + additional form field definitions that can be used with URLPARAM in the templatetopic
23# + AJAX form data submit
24
25#use strict;
26
27use vars
2824.73ms2171µs
# spent 97µs (22+75) within Foswiki::Plugins::RenderFormPlugin::Core::BEGIN@28 which was called: # once (22µs+75µs) by Foswiki::Plugins::RenderFormPlugin::BEGIN@66 at line 28
qw( $pluginName %defaults @requiredOptions @flagOptions %validOptions %options $defaultsInitialized @unknownParams @missingParams @invalidParams $formCounter );
# spent 97µs making 1 call to Foswiki::Plugins::RenderFormPlugin::Core::BEGIN@28 # spent 74µs making 1 call to vars::import
29
301600ns$pluginName = "RenderFormPlugin";
31
32# =========================
33sub _initDefaults {
34
35 %defaults = (
36 form => undef, ## DataForms definition
37 _DEFAULT => undef, ## same as form
38 topic => undef, ## default %TOPIC%XXXXXXXXXXX
39 script => 'save',
40 redirectto => undef, ## passed to script; redirect target after submit
41 templatetopic => undef,
42 topicparent => undef,
43 dontnotify => undef,
44 createbutton => 'Create',
45 editbutton => 'Update',
46 onlynewtopic => undef,
47 onlywikiname => undef,
48 hidden => undef, ## hidden form elements
49 mode => 'create', ## allowed: create / edit / view
50 dateformat => undef, ## date format for date form fields
51 hideheader => 0,
52 template => undef,
53 formName => undef,
54 order => undef,
55 text => undef,
56 missingparamsmsg =>
57'%RED% Sorry, missing required parameters: %MISSINGPARAMSLIST% %ENDCOLOR% <br/> Required parameters are %REQUIREDPARAMSLIST%',
58 unknownparamsmsg =>
59'%RED% Sorry, some parameters are unknown: %UNKNOWNPARAMSLIST% %ENDCOLOR% <br/> Allowed parameters are (see %SYSTEMWEB%.RenderFormPlugin topic for more details): %KNOWNPARAMSLIST%',
60 invalidparamsmsg =>
61'%RED% Sorry, some parameters are invalid for: %INVALIDPARAMSLIST% %ENDCOLOR% <br/> Valid parameters are (see %SYSTEMWEB%.RenderFormPlugin topic for more details): %VALIDPARAMSLIST%',
62 layout => undef,
63 fieldmarker => '@',
64 );
65
66 @requiredOptions = ('form');
67
68 @flagOptions =
69 ( 'dontnotify', 'onlywikiname', 'onlynewtopic', 'hideheader' );
70
71 %validOptions = (
72 'script' => [ 'edit', 'save' ],
73 'mode' => [ 'create', 'edit', 'view' ],
74 );
75
76 $formCounter = 0;
77
78 $defaultsInitialized = 1;
79
80}
81
82# =========================
83sub _initOptions {
84 my ( $attributes, $topic, $web ) = @_;
85
86 my %params = &Foswiki::Func::extractParameters($attributes);
87
88 ## handle default parameter:
89 $params{form} = $params{_DEFAULT}
90 if ( defined $params{_DEFAULT} ) && ( !defined $params{form} );
91
92 my @allOptions = keys %defaults;
93
94 @unknownParams = ();
95 foreach my $option ( keys %params ) {
96 push( @unknownParams, $option )
97 unless grep( /^\Q$option\E$/, @allOptions );
98 }
99 return 0 if $#unknownParams != -1;
100
101 my $tmplName = $params{template};
102 $tmplName =
103 ( Foswiki::Func::getPreferencesValue("\U${pluginName}_TEMPLATE\E")
104 || undef )
105 unless defined $tmplName;
106
107 my $cgi = Foswiki::Func::getCgiQuery();
108
109 $formCounter++;
110 my $formName =
111 defined $params{formName}
112 ? $params{formName}
113 : "renderForm$web$formCounter";
114
115 %options = ();
116 foreach my $option (@allOptions) {
117 my $v =
118 ( !defined $cgi->param('rfp_s_formName') )
119 || ( $cgi->param('rfp_s_formName') eq $formName )
120 ? $cgi->param("rfp_${option}")
121 : undef;
122 $v = $params{$option} unless defined $v;
123
124 if ( ( defined $tmplName ) && ( !defined $v ) ) {
125 $v = (
126 Foswiki::Func::getPreferencesFlag(
127 "\U${pluginName}_TEMPLATE_${tmplName}_${option}\E")
128 || undef
129 ) if grep /^\Q$option\E$/, @flagOptions;
130 $v = (
131 Foswiki::Func::getPreferencesValue(
132 "\U${pluginName}_TEMPLATE_${tmplName}_${option}\E")
133 || undef
134 ) unless defined $v;
135 $v = undef if ( defined $v ) && ( $v eq "" );
136 }
137
138 if ( defined $v ) {
139 if ( grep /^\Q$option\E$/, @flagOptions ) {
140 $options{$option} = ( $v !~ /^(0|false|no|off)$/i );
141 }
142 else {
143 $options{$option} = $v;
144 }
145 }
146 else {
147 if ( grep /^\Q$option\E$/, @flagOptions ) {
148 $v =
149 Foswiki::Func::getPreferencesFlag("\U${pluginName}_$option\E")
150 || undef;
151 }
152 else {
153 $v = Foswiki::Func::getPreferencesValue(
154 "\U${pluginName}_$option\E")
155 || undef;
156 }
157 $v = undef if ( defined $v ) && ( $v eq "" );
158 $options{$option} = ( defined $v ) ? $v : $defaults{$option};
159 }
160
161 }
162
163 $options{formName} = $formName unless defined $options{formName};
164
165 # automatic topic naming:
166 $options{topic} = $topic . 'XXXXXXXXXX' unless defined $options{topic};
167
168 # automatic mode change:
169 my ( $w, $t ) = _getWebAndTopic( $options{topic}, $web );
170 my $topicExists = Foswiki::Func::topicExists( $w, $t );
171 $options{mode} = 'view'
172 if ( ( $options{mode} eq $defaults{mode} )
173 && ( $options{topic} ne $topic . 'XXXXXXXXXX' )
174 && $topicExists );
175
176 # automatic form detection:
177 $options{form} = _detectForm($web)
178 if ( !defined $options{form} )
179 && ( defined $options{topic} )
180 && $topicExists;
181
182 # check required options:
183 @missingParams = ();
184 foreach my $option (@requiredOptions) {
185 push( @missingParams, $option ) unless defined $options{$option};
186 }
187 return 0 if $#missingParams != -1;
188
189 # validate options:
190 @invalidParams = ();
191 foreach my $option ( keys %validOptions ) {
192 push( @invalidParams, $option )
193 if ( defined $options{$option} )
194 && (
195 !grep( /^\Q$options{$option}\E$/i, @{ $validOptions{$option} } ) );
196 }
197 return 0 if $#invalidParams != -1;
198
199 return 1;
200}
201
202# =========================
203sub _detectForm {
204 my ($theWeb) = @_;
205 my ( $web, $topic ) = _getWebAndTopic( $options{topic}, $theWeb );
206 my $text = _readTopicText( $web, $topic, 0 );
207 my $formTopic = undef;
208
209 if ( $text =~ /\%META:FORM{(.*?)}\%/s ) {
210 my %params = Foswiki::Func::extractParameters($1);
211 my ( $w, $t ) = _getWebAndTopic( $params{name}, $web );
212 $formTopic = "$w.$t" if Foswiki::Func::topicExists( $w, $t );
213 }
214 return $formTopic;
215}
216
217# =========================
218sub render {
219 my ( $attributes, $theTopic, $theWeb ) = @_;
220
221 _initDefaults() unless $defaultsInitialized;
222
223 ## prevent possible mod_perl problems:
224 local ( %options, @unknownParams, @missingParams, @invalidParams );
225
226 _initOptions( $attributes, $theTopic, $theWeb )
227 || return (
228 $#unknownParams != -1 ? _createUnknownParamsMessage()
229 : (
230 $#missingParams != -1 ? _createMissingParamsMessage()
231 : _createInvalidParamsMessage()
232 )
233 );
234
235 my $topic =
236 defined $options{topic} ? $options{topic} : $theTopic . 'XXXXXXXXXX';
237
238 my ( $defsRef, $attrRef, $mandRef, $titlRef ) = _readDataFormsDef($theWeb);
239
240 _readTopicFormData( $attrRef, $topic, $theWeb )
241 if $options{mode} ne 'create';
242
243 $defsRef = _reorderDefs( $defsRef, $titlRef ) if defined $options{order};
244
245 my @defs = @{$defsRef};
246 my %attr = %{$attrRef};
247 my @mand = @{$mandRef};
248 my %titl = %{$titlRef};
249
250 my $text = "";
251 my $cgi = Foswiki::Func::getCgiQuery();
252
253 #_dump(\@defs);
254
255 my $formName = $options{formName};
256
257 $text .= $cgi->start_form(
258 -method => "post",
259 -onSubmit => "return ${formName}CheckFormData();",
260 -name => $formName,
261 -action =>
262 Foswiki::Func::getScriptUrl( $theWeb, $topic, $options{script} )
263 );
264 $text .= $cgi->a( { -name => "$formName" }, "" );
265
266 $options{topicparent} = "$theWeb.$theTopic"
267 unless defined $options{topicparent};
268
269 $text .=
270 $cgi->hidden( -name => 'formtemplate', -default => $options{form} );
271 $text .= $cgi->hidden(
272 -name => 'templatetopic',
273 -default => $options{templatetopic}
274 ) if defined $options{templatetopic};
275 $text .= $cgi->hidden( -name => 'text', -default => $options{text} )
276 if defined $options{text} && !defined $options{templatetopic};
277 $text .=
278 $cgi->hidden( -name => 'topicparent', -default => $options{topicparent} )
279 if defined $options{topicparent};
280 $text .= $cgi->hidden(
281 -name => 'onlynewtopic',
282 -default => ( $options{mode} eq 'edit' ? 'off' : 'on' )
283 ) if ( !defined $options{onlynewtopic} ) || $options{onlynewtopic};
284 $text .= $cgi->hidden( -name => 'onlywikiname', -default => 'on' )
285 if $options{onlywikiname};
286 $text .=
287 $cgi->hidden( -name => 'dontnotify', -default => $options{dontnotify} )
288 if defined $options{dontnotify};
289 $text .=
290 $cgi->hidden( -name => 'redirectto', -default => $options{redirectto} )
291 if defined $options{redirectto};
292
293 $text .= _createJavaScript( \@mand, $formName )
294 unless $options{mode} eq 'view';
295
296 if ( defined $options{layout} && _layoutTopicExists($theWeb) ) {
297 $text .= _renderUserLayout( $topic, $theWeb, $titlRef );
298 }
299 else {
300 my @hidden =
301 ( defined $options{hidden} && $options{hidden} !~ /^\s*$/ )
302 ? split( /[,\|\;]/, $options{hidden} )
303 : ();
304 my $hiddenText = "";
305 $text .= "\n";
306
307 my $button = _getSwitchButton( $theTopic, $theWeb );
308 $text .= "| * "
309 . ( $options{mode} eq 'create' ? "<nop>" : "" )
310 . "$topic$button / $options{form} * ||\n"
311 unless $options{hideheader};
312
313 foreach my $def (@defs) {
314 if ( grep( /^\Q$$def{name}\E$/, @hidden ) ) {
315 $hiddenText .= $cgi->hidden(
316 -name => $$def{name},
317 -default => $$def{values}[0]{name}
318 );
319 next;
320 }
321 my ( $td, $tadd ) = _renderFormField( $cgi, $def, $formName );
322 $text .= '| *'
323 . $cgi->span(
324 { title => $$def{tooltip} },
325 " "
326 . $$def{title}
327 . ( $$def{attr} =~ /M/ ? " %RED%*%ENDCOLOR%" : " " )
328 . $tadd
329 )
330 . '*|'
331 . $td . '|';
332 $text .= "\n";
333 }
334 $text .= "|| %RED%*%ENDCOLOR% indicates mandatory fields|\n"
335 if $#mand != -1;
336 $text .= $cgi->submit(
337 -name => 'Save',
338 -value => $options{ $options{mode} . 'button' }
339 ) unless $options{mode} eq 'view';
340 $text .= $hiddenText;
341 }
342 $text .= $cgi->end_form();
343 $text .= "\n";
344 return $text;
345}
346
347# =========================
348sub _layoutTopicExists {
349 my ($theWeb) = @_;
350 my ( $topic, $web );
351 ($topic) = split( /\#/, $options{layout} );
352 ( $web, $topic ) = _getWebAndTopic( $topic, $theWeb );
353 return Foswiki::Func::topicExists( $web, $topic );
354}
355
356# =========================
357sub _renderUserLayout {
358 my ( $topic, $web, $a ) = @_;
359
360 my $cgi = Foswiki::Func::getCgiQuery();
361 my $formName = $options{formName};
362
363 my $text = _readUserLayout($web);
364
365 $text =~
366s/\Q$options{fieldmarker}FORMTOPIC$options{fieldmarker}\E/$options{form}/g;
367
368 $text =~ s/\Q$options{fieldmarker}TOPIC$options{fieldmarker}\E/$topic/g;
369
370 my $button =
371 $options{mode} ne 'view'
372 ? $cgi->submit(
373 -name => 'Save',
374 -value => $options{ $options{mode} . 'button' }
375 )
376 : "";
377 $text =~ s/\Q$options{fieldmarker}SUBMIT$options{fieldmarker}\E/$button/g;
378
379 my $switch = _getSwitchButton( $topic, $web );
380 $text =~ s/\Q$options{fieldmarker}SWITCH$options{fieldmarker}\E/$switch/g;
381
382 $text =~
383s/\Q$options{fieldmarker}\EOPTION[\(\[\{]([^\)\}\]\Q$options{fieldmarker}\E]+)[\)\}\]]\Q$options{fieldmarker}\E/$options{$1}/sg;
384 $text =~
385s/\Q$options{fieldmarker}OPTION$options{fieldmarker}\E/join(", ",sort keys %options)/eg;
386
387 my $hidden = "";
388 foreach my $name ( keys %{$a} ) {
389 my $def = $$a{$name};
390 my $title = $$def{title};
391
392 if ( $text =~
393s/(\Q$options{fieldmarker}$title$options{fieldmarker}\E)/join(" ",_renderFormField($cgi,$def,$formName))/eg
394 )
395 {
396 Foswiki::Func::writeDebug("$1 substituted")
397 if $Foswiki::Plugins::RenderFormPlugin::debug;
398 }
399 else {
400 $hidden .= $cgi->hidden(
401 -name => $name,
402 -default => $$def{values}[0]{name}
403 );
404 }
405 }
406 $text .= "\n$hidden";
407
408 return $text;
409}
410
411# =========================
412sub _readUserLayout {
413 my ($web) = @_;
414
415 my $layout = undef;
416
417 my ( $lt, $name ) = split( /\#/, $options{layout} );
418
419 my ( $w, $t ) = _getWebAndTopic( $lt, $web );
420 my $text = _readTopicText( $w, $t );
421
422 my $firstlayout = undef;
423
424 while (
425 ( !defined $layout )
426 && ( $text =~
427 s/\%STARTRENDERFORMLAYOUT\{(.*?)\}\%(.*?)\%STOPRENDERFORMLAYOUT\%//s
428 )
429 )
430 {
431 my ( $p, $l ) = ( $1, $2 );
432 my %params = Foswiki::Func::extractParameters($p);
433 my $pname = $params{name};
434 $pname = $params{_DEFAULT} unless defined $pname;
435 if (
436 ( defined $name )
437 && ( defined $pname )
438 && ( $pname eq $name )
439 && ( ( !defined $params{mode} )
440 || ( $params{mode} eq $options{mode} ) )
441 )
442 {
443 $layout = $l;
444 }
445 elsif ( ( !defined $name ) && ( !defined $pname ) ) {
446 if ( ( defined $params{mode} )
447 && ( $params{mode} eq $options{mode} ) )
448 {
449 $layout = $l;
450 }
451 elsif (( defined $params{_DEFAULT} )
452 && ( $params{_DEFAULT} eq $options{mode} ) )
453 {
454 $layout = $l;
455 }
456 }
457
458 $firstlayout = $l unless defined $firstlayout;
459 }
460
461 if (
462 ( !defined $layout )
463 && ( $text =~
464 s/\%STARTRENDERFORMLAYOUT\%(.*?)\%STOPRENDERFORMLAYOUT\%//s )
465 )
466 {
467 $layout = $1;
468 }
469
470 $layout = $firstlayout unless defined $layout;
471
472 if ( !defined $layout ) {
473 $text =~ s/\%META[^\%]*\%//sg;
474 $layout = $text;
475 }
476
477 return $layout;
478}
479
480# =========================
481sub _getSwitchButton {
482 my ( $theTopic, $theWeb ) = @_;
483 my $formName = $options{formName};
484 my $cgi = Foswiki::Func::getCgiQuery();
485 my $buttonmode =
486 $options{mode} eq 'view' ? 'edit'
487 : $options{mode} eq 'edit' ? 'view'
488 : '';
489
490 ## preserve all query parameters and overwrite some
491 my $newcgi = new CGI($cgi);
492 $newcgi->param( 'rfp_mode', $buttonmode );
493 $newcgi->param( 'rfp_s_formName', $formName );
494 $newcgi->param( 't', time() );
495 my $href = $newcgi->self_url() . "#$formName";
496
497 my $button =
498 $buttonmode ne ''
499 ? $cgi->span(
500 { -style => 'font-size: 0.6em;' },
501 $cgi->a(
502 { -title => uc($buttonmode), -href => $href },
503 "[\U$buttonmode form\E]"
504 )
505 )
506 : "";
507
508 return $button;
509}
510
511# =========================
512sub _reorderDefs {
513 my ( $defs, $attr ) = @_;
514
515 my @newdefs = ();
516 if ( $options{order} =~ /\[\:(alpha|dalpha|ralpha|num|dnum|rnum)\:\]/i ) {
517 my $sfvar = lc($1);
518 my @sattr;
519 @sattr = sort { $a cmp $b } keys %{$attr} if ( $sfvar eq 'alpha' );
520 @sattr = sort { $b cmp $a } keys %{$attr}
521 if ( $sfvar eq 'dalpha' ) || ( $sfvar eq 'ralpha' );
522 @sattr = sort { _int($a) <=> _int($b) } keys %{$attr}
523 if ( $sfvar eq 'num' );
524 @sattr = sort { _int($b) <=> _int($a) } keys %{$attr}
525 if ( $sfvar eq 'dnum' ) || ( $sfvar eq 'rnum' );
526 for my $a (@sattr) {
527 push( @newdefs, $$attr{$a} ) if defined $$attr{$a}{name};
528 }
529
530 }
531 else {
532 my @order = split( /\s*[,\|\;]\s*/, $options{order} );
533 foreach my $a (@order) {
534 push @newdefs, $$attr{$a} if defined $$attr{$a};
535 }
536
537 foreach my $def ( @{$defs} ) {
538 push @newdefs, $def unless grep( /^\Q$$def{name}\E$/, @order );
539 }
540 }
541
542 return \@newdefs;
543}
544
545# =========================
546sub _renderFormField {
547 my ( $cgi, $def, $formName ) = @_;
548 my $td = ""; # form field cell
549 my $tadd = ""; # addition to the form field name
550
551 if ( lc( $$def{type} ) eq 'label' ) {
552 $td = $$def{value};
553 }
554 elsif ( lc( $$def{type} ) eq 'select' ) {
555 $td = _renderOptions($def);
556 $td =
557 '<select name="'
558 . _encode( $$def{name} )
559 . '" size="'
560 . _encode( $$def{size} ) . '">'
561 . $td
562 . '</select>'
563 if $options{mode} ne 'view';
564 }
565 elsif ( lc( $$def{type} ) eq 'select+multi' ) {
566 $td = _renderOptions($def);
567 $td =
568 '<select multiple="multiple" name="'
569 . _encode( $$def{name} )
570 . '" size="'
571 . _encode( $$def{size} ) . '">'
572 . $td
573 . '</select>'
574 if $options{mode} ne 'view';
575 }
576 elsif ( lc( $$def{type} ) eq 'checkbox+buttons' ) {
577 $td = _renderButtons($def);
578 $tadd = "<br/>"
579 . $cgi->button(
580 -value => "Set all",
581 -onClick => qq@${formName}CheckAll("$$def{name}",true)@
582 )
583 . ' '
584 . $cgi->button(
585 -value => "Clear all",
586 -onClick => qq@${formName}CheckAll("$$def{name}",false)@
587 ) if ( $options{mode} ne 'view' );
588 }
589 elsif ( lc( $$def{type} ) eq 'checkbox' ) {
590 $td = _renderButtons($def);
591 }
592 elsif ( lc( $$def{type} ) eq 'radio' ) {
593 $td = _renderButtons($def);
594 }
595 elsif ( lc( $$def{type} ) eq 'textarea' ) {
596 $$def{size} =~ /(\d+)x(\d+)/i;
597 my ( $cols, $rows ) = ( $1, $2 );
598 my $tadata = $$def{value};
599 $tadata =~ s/%([0-9a-f]{2})/chr(hex("0x$1"))/eig;
600 if ( $options{mode} eq 'view' ) {
601 $tadata =~ s/\r?\n/<br \/>/g;
602 $td = $tadata;
603 $td = '&nbsp;' if $tadata eq "";
604 }
605 else {
606 $tadata =~ s/([\r\n])/'&#'.ord($1).';'/eg;
607 my $old = $cgi->autoEscape();
608 $cgi->autoEscape(0);
609 $td = '<noautolink>'
610 . $cgi->textarea(
611 {
612 -title => $$def{tooltip},
613 -rows => $rows,
614 -columns => $cols,
615 -name => $$def{name},
616 -default => qq@$tadata@
617 }
618 ) . '</noautolink>';
619 $cgi->autoEscape($old);
620
621 }
622 }
623 elsif ( lc( $$def{type} ) eq 'date' ) {
624 if ( $options{mode} eq 'view' ) {
625 $td = $$def{value};
626 $td = '&nbsp;' if $$def{value} eq "";
627 }
628 else {
629 my $dateformat =
630 defined $options{dateformat}
631 ? $options{dateformat}
632 : Foswiki::Func::getPreferencesValue('JSCALENDARDATEFORMAT');
633 $dateformat = "%d %b %Y" unless defined $dateformat;
634 my $id = $formName . $$def{name};
635 $td = $cgi->textfield(
636 {
637 -id => $id,
638 -name => $$def{name},
639 -default => $$def{value},
640 -size => $$def{size},
641 -readonly => 'readonly'
642 }
643 )
644 . $cgi->image_button(
645 -name => 'calendar',
646 -src => '%PUBURLPATH%/%SYSTEMWEB%/JSCalendarContrib/img.gif',
647 -alt => 'Calendar',
648 -title => 'Calendar',
649 -onClick =>
650 qq@javascript: return showCalendar('$id','$dateformat')@
651 );
652 }
653 }
654 else {
655 if ( $options{mode} eq 'view' ) {
656 $td =
657 ( !defined $$def{value} || $$def{value} eq "" )
658 ? "&nbsp;"
659 : $$def{value};
660 }
661 else {
662 $td = $cgi->textfield(
663 {
664 -size => $$def{size},
665 -name => $$def{name},
666 -default => $$def{value}
667 }
668 );
669 }
670 }
671 return ( $td, $tadd );
672}
673
674# =========================
675sub _createJavaScript {
676 my ( $mandRef, $formName ) = @_;
677 my $mandatoryFields =
678 '"' . join( '","', map( _encode($_), @{$mandRef} ) ) . '"';
679 my $text = qq@<noautolink><script type="text/javascript">\n
680 //<!--[
681 function ${formName}CheckAll(name, check) {
682 var formname="${formName}";
683 for (var i=0; i<document.forms[formname].elements[name].length; i++) {
684 document.forms[formname].elements[name][i].checked=check;
685 }
686 }
687 function ${formName}CheckFormData() {
688 var formname="$formName";
689 var mandatoryFields = new Array(${mandatoryFields});
690 var errorFields = new Array();
691 for (var i=0; i<mandatoryFields.length; i++) {
692 var fieldname = mandatoryFields[i];
693 var element = document.forms[formname].elements[mandatoryFields[i]];
694 var error = true;
695
696 if (element.options) {
697 for (var j=0; j<element.options.length; j++) {
698 if (element.options[j].selected == true) { error = false; break; }
699 }
700 } else if (element.length) {
701 for (var j=0; j<element.length; j++) {
702 if (element[j].checked == true) { error = false; break; }
703 }
704
705 } else {
706 error = (element.value.search(/^ *\$/)!=-1);
707 }
708 if (error) errorFields.push(fieldname);
709 }
710
711 if (errorFields.length>0) alert("Please fill in mandatory fields: \\n"+errorFields.join(", "));
712
713 return errorFields.length==0;
714 }
715 //]-->
716 </script></noautolink>\n@;
717 return $text;
718}
719
720# =========================
721sub _readTopicFormData {
722 my ( $attr, $topic, $theWeb ) = @_;
723
724 my ( $w, $t ) = _getWebAndTopic( $topic, $theWeb );
725
726 my $data = _readTopicText( $w, $t, 0 );
727
728 my $foundForm = 0;
729 foreach my $line ( split( /[\r\n]/, $data ) ) {
730 if ( $line =~ /\%META:FORM{(.*?)}\%/ ) {
731 my %params = Foswiki::Func::extractParameters($1);
732 $foundForm = ( $params{name} eq $options{form} )
733 || ( $params{name} eq "$theWeb.$options{form}" );
734 next;
735 }
736
737 if ( $foundForm && ( $line =~ /\%META:FIELD{(.*?)}\%/ ) ) {
738 my %params = Foswiki::Func::extractParameters($1);
739
740 if ( defined $$attr{ $params{name} }
741 && $$attr{ $params{name} }{type} =~
742 /^(text|textarea|label|date)$/ )
743 {
744 $$attr{ $params{name} }{value} = $params{value};
745 }
746 else {
747 $$attr{ $params{name} }{default} = $params{value};
748 }
749
750 }
751
752 }
753
754}
755
756# =========================
757sub _encode {
758 my ($text) = @_;
759
760 $text =~ s/\"/\&quot;/g;
761 $text =~ s/[\r\n]/<br\/>/g;
762
763 #$text=~s/\w/<nop>/g;
764 return $text;
765}
766
767# =========================
768sub _renderButtons {
769 my ($def) = @_;
770 my $name = $$def{name};
771 my $type = $$def{type};
772 my $size = $$def{size};
773 my $valuesRef = $$def{values};
774
775 my @defaults =
776 defined $$def{default} ? split( /,\s*/, $$def{default} ) : ();
777
778 $type = 'checkbox' if $type =~ /^checkbox/;
779
780 my $text = "";
781 my $counter = 0;
782 foreach my $value ( @{$valuesRef} ) {
783 if ( $options{mode} eq 'view' ) {
784 if ( grep( /^\Q$$value{name}\E$/, @defaults ) ) {
785 $text .=
786 qq@<span title="@
787 . _encode( $$value{tooltip} )
788 . qq@"> $$value{name} </span>@;
789 }
790 else {
791 $counter--;
792 }
793
794 }
795 else {
796 my $checked =
797 grep( /^\Q$$value{name}\E$/, @defaults )
798 ? 'checked="ckecked"'
799 : "";
800 $text .=
801 '<input '
802 . $checked
803 . ' type="'
804 . $type
805 . '" name="'
806 . _encode($name)
807 . '" title="'
808 . _encode( $$value{tooltip} )
809 . '" value="'
810 . _encode( $$value{name} ) . '"> '
811 . $$value{name}
812 . ' </input> ';
813 }
814 $counter++;
815 if ( ( $size > 0 ) && ( $counter >= $size ) ) {
816 $text .= '<br />';
817 $counter = 0;
818 }
819 }
820 return $text eq "" ? '&nbsp;' : $text;
821}
822
823# =========================
824sub _renderOptions {
825 my ($defRef) = @_;
826 my $text = "";
827 my $valuesRef = $$defRef{values};
828 my @defaults =
829 defined $$defRef{default} ? split( /,\s*/, $$defRef{default} ) : ();
830 foreach my $value ( @{$valuesRef} ) {
831 if ( $options{mode} eq 'view' ) {
832 $text .=
833 qq@<span title="@
834 . _encode( $$value{tooltip} )
835 . qq@"> $$value{name} </span>@
836 if grep( /^\Q$$value{name}\E$/, @defaults );
837 }
838 else {
839 my $selected =
840 grep( /^\Q$$value{name}\E$/, @defaults )
841 ? 'selected="selected"'
842 : "";
843 $text .=
844 '<option '
845 . $selected
846 . ' title="'
847 . _encode( $$value{tooltip} )
848 . '"><nop>'
849 . $$value{name}
850 . '</option>';
851 }
852 }
853 return $text eq "" ? '&nbsp;' : $text;
854}
855
856# =========================
857sub _getWebAndTopic {
858 my ( $topic, $web ) = @_;
859 my ( $w, $t ) = split( /\./, $topic );
860 if ( !defined $t ) {
861 $t = $w;
862 $w = $web;
863 }
864
865 return ( $w, $t );
866
867}
868
869# =========================
870sub _readDataFormsDef {
871 my ($theWeb) = @_;
872
873 my ( $web, $topic ) = _getWebAndTopic( $options{form}, $theWeb );
874
875 my @defs = ();
876 my %attr = ();
877 my @mand = ();
878 my %titl = ();
879
880 my $data = _readTopicText( $web, $topic );
881
882 foreach my $line ( split( /[\r\n]+/, $data ) ) {
883 my @cols = split( /\s*\|\s*/, $line );
884 chomp($line);
885 next if ( $#cols < 3 );
886 next if $cols[1] =~ /\*[^\*]*\*/; ## ignore header
887
888 my @values = ();
889 my $value = $cols[4];
890
891 if ( !defined $value || $value =~ /^\s*$/ ) {
892 @values = @{ _getFormFieldValues( $cols[1], $web ) };
893 }
894 else {
895 foreach my $name ( split( /\s*,\s*/, $value ) ) {
896 push( @values,
897 { name => $name, type => 'option', tooltip => $name } );
898 }
899 }
900
901 my $name = $cols[1];
902 $name =~ s/\W//g;
903
904 push @defs,
905 {
906 name => $name,
907 title => $cols[1],
908 type => _get( $cols[2], 'text' ),
909 size => _get( $cols[3], 80 ),
910 value => _get( $value, "" ),
911 values => \@values,
912 tooltip => _get( $cols[5], $cols[1] ),
913 attr => _get( $cols[6], "" )
914 };
915 $attr{$name} = $defs[$#defs];
916 $titl{ $cols[1] } = $defs[$#defs];
917
918 push @mand, $name if $defs[$#defs]{attr} =~ /M/i;
919
920 }
921 return ( \@defs, \%attr, \@mand, \%titl );
922}
923
924# =========================
925sub _getFormFieldValues {
926 my ( $topic, $web ) = @_;
927
928 my @values = ();
929 my $data = _readTopicText( $web, $topic );
930 foreach my $line ( split( /[\r\n]+/, $data ) ) {
931 chomp($line);
932 my @cols = split( /\s*\|\s*/, $line );
933 next if $#cols < 1;
934 next if $cols[1] =~ /\*[^\*]*\*/;
935 push(
936 @values,
937 {
938 name => $cols[1],
939 value => $cols[1],
940 type => _get( $cols[2], 'option' ),
941 tooltip => _get( $cols[3], $cols[1] )
942 }
943 );
944 }
945
946 return \@values;
947}
948
949# =========================
950sub _createMissingParamsMessage {
951 my $msg;
952 $msg = Foswiki::Func::getPreferencesValue("MISSINGPARAMSMSG") || undef;
953 $msg = $defaults{missingparamsmsg} unless defined $msg;
954 $msg =~ s/\%MISSINGPARAMSLIST\%/join(', ', sort @missingParams)/eg;
955 $msg =~ s/\%REQUIREDPARAMSLIST\%/join(', ', sort @requiredOptions)/eg;
956 return $msg;
957}
958
959# =========================
960sub _createUnknownParamsMessage {
961 my $msg;
962 $msg = Foswiki::Func::getPreferencesValue("UNKNOWNPARAMSMSG") || undef;
963 $msg = $defaults{unknownparamsmsg} unless defined $msg;
964 $msg =~ s/\%UNKNOWNPARAMSLIST\%/join(', ', sort @unknownParams)/eg;
965 $msg =~ s/\%KNOWNPARAMSLIST\%/join(', ', sort keys %defaults)/eg;
966 return $msg;
967}
968
969# =========================
970sub _createInvalidParamsMessage {
971 my $msg;
972 $msg = Foswiki::Func::getPreferencesValue("INVALIDPARAMSMSG") || undef;
973 $msg = $defaults{invalidparamsmsg} unless defined $msg;
974 $msg =~ s/\%INVALIDPARAMSLIST\%/join(', ', sort @invalidParams)/eg;
975 my $list = "";
976 foreach my $p (@invalidParams) {
977 $list .= "$p=(" . join( '|', @{ $validOptions{$p} } ) . ") ";
978 }
979 $msg =~ s/\%VALIDPARAMSLIST\%/$list/eg;
980 return $msg;
981}
982
983# =========================
984sub _readTopicText {
985 my ( $theWeb, $theTopic, $dontExpand ) = @_;
986 my $text = '';
987 if ( $Foswiki::Plugins::VERSION >= 1.010 ) {
988 $text = &Foswiki::Func::readTopicText( $theWeb, $theTopic, '', 1 );
989 }
990 else {
991 $text = &Foswiki::Func::readTopic( $theWeb, $theTopic );
992 }
993
994 #if ((!defined $dontExpand) || (!$dontExpand)) {
995 $text =~ s/(\%RENDERFORM{.*?}%)/<verbatim>\n$1<\/verbatim>/g;
996 $text =~
997s/(\%STARTRENDERFORMLAYOUT.*?STOPRENDERFORMLAYOUT\%)/<verbatim>\n$1\n<\/verbatim>/sg;
998
999 $text = Foswiki::Func::expandCommonVariables( $text, $theTopic, $theWeb );
1000
1001 #}
1002 # return raw topic text, including meta data
1003 return $text;
1004}
1005
1006# =========================
1007sub _get {
1008 return defined $_[0] ? $_[0] : $_[1];
1009}
1010
1011# =========================
1012sub _int {
1013 return $_[0] =~ /(\d+)/ ? $1 : ord( substr( $_[0], 0, 1 ) );
1014}
1015
1016# =========================
1017sub _dump {
1018 eval {
1019273µs264µs
# spent 41µs (17+23) within Foswiki::Plugins::RenderFormPlugin::Core::BEGIN@1019 which was called: # once (17µs+23µs) by Foswiki::Plugins::RenderFormPlugin::BEGIN@66 at line 1019
use Data::Dumper;
# spent 41µs making 1 call to Foswiki::Plugins::RenderFormPlugin::Core::BEGIN@1019 # spent 23µs making 1 call to Exporter::import
1020 Foswiki::Func::writeWarning( Data::Dumper->Dump( \@_ ) );
1021 };
1022}
102312µs1;