← 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:26:48 2011

Filename/usr/local/src/github.com/foswiki/core/lib/Foswiki/Plugins/PreferencesPlugin.pm
StatementsExecuted 3419 statements in 18.4ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
11311114.6ms17.0msFoswiki::Plugins::PreferencesPlugin::::beforeCommonTagsHandlerFoswiki::Plugins::PreferencesPlugin::beforeCommonTagsHandler
1131112.36ms2.36msFoswiki::Plugins::PreferencesPlugin::::CORE:matchFoswiki::Plugins::PreferencesPlugin::CORE:match (opcode)
51194µs141µsFoswiki::Plugins::PreferencesPlugin::::postRenderingHandlerFoswiki::Plugins::PreferencesPlugin::postRenderingHandler
51128µs28µsFoswiki::Plugins::PreferencesPlugin::::CORE:substFoswiki::Plugins::PreferencesPlugin::CORE:subst (opcode)
11125µs32µsFoswiki::Plugins::PreferencesPlugin::::BEGIN@27Foswiki::Plugins::PreferencesPlugin::BEGIN@27
51119µs19µsFoswiki::Plugins::PreferencesPlugin::::CORE:regcompFoswiki::Plugins::PreferencesPlugin::CORE:regcomp (opcode)
11118µs18µsFoswiki::Plugins::PreferencesPlugin::::initPluginFoswiki::Plugins::PreferencesPlugin::initPlugin
11116µs67µsFoswiki::Plugins::PreferencesPlugin::::BEGIN@33Foswiki::Plugins::PreferencesPlugin::BEGIN@33
11116µs34µsFoswiki::Plugins::PreferencesPlugin::::BEGIN@28Foswiki::Plugins::PreferencesPlugin::BEGIN@28
11110µs10µsFoswiki::Plugins::PreferencesPlugin::::BEGIN@30Foswiki::Plugins::PreferencesPlugin::BEGIN@30
1119µs9µsFoswiki::Plugins::PreferencesPlugin::::BEGIN@31Foswiki::Plugins::PreferencesPlugin::BEGIN@31
0000s0sFoswiki::Plugins::PreferencesPlugin::::_generateControlButtonsFoswiki::Plugins::PreferencesPlugin::_generateControlButtons
0000s0sFoswiki::Plugins::PreferencesPlugin::::_generateEditButtonFoswiki::Plugins::PreferencesPlugin::_generateEditButton
0000s0sFoswiki::Plugins::PreferencesPlugin::::_generateEditFieldFoswiki::Plugins::PreferencesPlugin::_generateEditField
0000s0sFoswiki::Plugins::PreferencesPlugin::::_getFieldFoswiki::Plugins::PreferencesPlugin::_getField
0000s0sFoswiki::Plugins::PreferencesPlugin::::_saveSetFoswiki::Plugins::PreferencesPlugin::_saveSet
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# Plugin for Foswiki - The Free and Open Source Wiki, http://foswiki.org/
3#
4# Copyright (C) 2005-2009 Foswiki Contributors.
5# All Rights Reserved. Foswiki Contributors are listed in the
6# AUTHORS file in the root of this distribution.
7# NOTE: Please extend that file, not this notice.
8#
9# This program is free software; you can redistribute it and/or
10# modify it under the terms of the GNU General Public License
11# as published by the Free Software Foundation; either version 2
12# of the License, or (at your option) any later version. For
13# more details read LICENSE in the root of this distribution.
14#
15# This program is distributed in the hope that it will be useful,
16# but WITHOUT ANY WARRANTY; without even the implied warranty of
17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18#
19# For licensing info read LICENSE file in the Foswiki root.
20
21# Still do to:
22# Handle continuation lines (see Prefs::parseText). These should always
23# go into a text area.
24
25package Foswiki::Plugins::PreferencesPlugin;
26
27246µs239µs
# spent 32µs (25+7) within Foswiki::Plugins::PreferencesPlugin::BEGIN@27 which was called: # once (25µs+7µs) by Foswiki::Plugin::BEGIN@2.12 at line 27
use strict;
# spent 32µs making 1 call to Foswiki::Plugins::PreferencesPlugin::BEGIN@27 # spent 7µs making 1 call to strict::import
28245µs252µs
# spent 34µs (16+18) within Foswiki::Plugins::PreferencesPlugin::BEGIN@28 which was called: # once (16µs+18µs) by Foswiki::Plugin::BEGIN@2.12 at line 28
use warnings;
# spent 34µs making 1 call to Foswiki::Plugins::PreferencesPlugin::BEGIN@28 # spent 18µs making 1 call to warnings::import
29
30238µs110µs
# spent 10µs within Foswiki::Plugins::PreferencesPlugin::BEGIN@30 which was called: # once (10µs+0s) by Foswiki::Plugin::BEGIN@2.12 at line 30
use Foswiki::Func (); # The plugins API
# spent 10µs making 1 call to Foswiki::Plugins::PreferencesPlugin::BEGIN@30
31255µs19µs
# spent 9µs within Foswiki::Plugins::PreferencesPlugin::BEGIN@31 which was called: # once (9µs+0s) by Foswiki::Plugin::BEGIN@2.12 at line 31
use Foswiki::Plugins (); # For the API version
# spent 9µs making 1 call to Foswiki::Plugins::PreferencesPlugin::BEGIN@31
32
3322.55ms2117µs
# spent 67µs (16+50) within Foswiki::Plugins::PreferencesPlugin::BEGIN@33 which was called: # once (16µs+50µs) by Foswiki::Plugin::BEGIN@2.12 at line 33
use vars qw( @shelter );
# spent 67µs making 1 call to Foswiki::Plugins::PreferencesPlugin::BEGIN@33 # spent 50µs making 1 call to vars::import
34
3512µsour $VERSION = '$Rev$';
3611µsour $RELEASE = '1.1.1';
3711µsour $SHORTDESCRIPTION =
38 'Allows editing of preferences using fields predefined in a form';
3911µsour $NO_PREFS_IN_TOPIC = 1;
40
4112µsmy $MARKER = "\007";
42
43# Markers used during form generation
4412µsmy $START_MARKER = $MARKER . 'STARTPREF' . $MARKER;
4512µsmy $END_MARKER = $MARKER . 'ENDPREF' . $MARKER;
46
47
# spent 18µs within Foswiki::Plugins::PreferencesPlugin::initPlugin which was called: # once (18µs+0s) by Foswiki::Plugin::__ANON__[/usr/local/src/github.com/foswiki/core/lib/Foswiki/Plugin.pm:235] at line 228 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Plugin.pm
sub initPlugin {
48
49 # check for Plugins.pm versions
50316µs if ( $Foswiki::Plugins::VERSION < 1.026 ) {
51 Foswiki::Func::writeWarning(
52 'Version mismatch between PreferencesPlugin and Plugins.pm');
53 return 0;
54 }
55 @shelter = ();
56
57 return 1;
58}
59
60
# spent 17.0ms (14.6+2.36) within Foswiki::Plugins::PreferencesPlugin::beforeCommonTagsHandler which was called 1131 times, avg 15µs/call: # 1131 times (14.6ms+2.36ms) by Foswiki::Plugin::invoke at line 287 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Plugin.pm, avg 15µs/call
sub beforeCommonTagsHandler {
61 ### my ( $text, $topic, $web ) = @_;
62339315.5ms my $topic = $_[1];
63 my $web = $_[2];
6411312.36ms return unless ( $_[0] =~ m/%EDITPREFERENCES(?:{(.*?)})?%/ );
# spent 2.36ms making 1131 calls to Foswiki::Plugins::PreferencesPlugin::CORE:match, avg 2µs/call
65
66 require CGI;
67 require Foswiki::Attrs;
68 my $formDef;
69 my $attrs = new Foswiki::Attrs($1);
70 if ( defined( $attrs->{_DEFAULT} ) ) {
71 my ( $formWeb, $form ) =
72 Foswiki::Func::normalizeWebTopicName( $web, $attrs->{_DEFAULT} );
73
74 # SMELL: Unpublished API. No choice, though :-(
75 require Foswiki::Form; # SMELL
76 $formDef =
77 new Foswiki::Form( $Foswiki::Plugins::SESSION, $formWeb, $form );
78 }
79
80 my $query = Foswiki::Func::getCgiQuery();
81
82 my $action = lc( $query->param('prefsaction') || '' );
83 $query->Delete('prefsaction');
84 $action =~ s/\s.*$//;
85
86 if ( $action eq 'edit' ) {
87 Foswiki::Func::setTopicEditLock( $web, $topic, 1 );
88
89 # Replace setting values by form fields but not inside comments Item4816
90 # and also not inside verbatim blocks Item1117
91 my $outtext = '';
92 my $insidecomment = 0;
93 my $insideverbatim = 0;
94 foreach my $token ( split /(<!--|-->|<\/?verbatim\b[^>]*>)/, $_[0] ) {
95 if ( !$insideverbatim and $token =~ /<!--/ ) {
96 $insidecomment++;
97 }
98 elsif ( !$insideverbatim and $token =~ /-->/ ) {
99 $insidecomment-- if ( $insidecomment > 0 );
100 }
101 elsif ( $token =~ /<verbatim/ ) {
102 $insideverbatim++;
103 }
104 elsif ( $token =~ /<\/verbatim/ ) {
105 $insideverbatim-- if ( $insideverbatim > 0 );
106 }
107 elsif ( !$insidecomment and !$insideverbatim ) {
108 $token =~
109s/^($Foswiki::regex{setRegex})($Foswiki::regex{tagNameRegex})\s*\=(.*$(?:\n[ \t]+[^\s*].*$)*)/
110 $1._generateEditField($web, $topic, $3, $4, $formDef)/gem;
111 }
112 $outtext .= $token;
113 }
114 $_[0] = $outtext;
115
116 $_[0] =~ s/%EDITPREFERENCES({.*?})?%/
117 _generateControlButtons($web, $topic)/ge;
118 my $viewUrl = Foswiki::Func::getScriptUrl( $web, $topic, 'viewauth' );
119 my $startForm = CGI::start_form(
120 -name => 'editpreferences',
121 -method => 'post',
122 -action => $viewUrl
123 );
124 $startForm =~ s/\s+$//s;
125 my $endForm = CGI::end_form();
126 $endForm =~ s/\s+$//s;
127 $_[0] =~
128 s/^(.*?)$START_MARKER(.*)$END_MARKER(.*?)$/$1$startForm$2$endForm$3/s;
129 $_[0] =~ s/$START_MARKER|$END_MARKER//gs;
130 }
131
132 if ( $action eq 'cancel' ) {
133 Foswiki::Func::setTopicEditLock( $web, $topic, 0 );
134
135 }
136 elsif ( $action eq 'save' ) {
137
138 # Make sure the request came from POST
139 if ( $query && $query->method() && uc( $query->method() ) ne 'POST' ) {
140
141 # silently ignore it if the request didn't come from a POST
142 }
143 else {
144 my ( $meta, $text ) = Foswiki::Func::readTopic( $web, $topic );
145
146 # SMELL: unchecked implicit untaint of value?
147 # $text =~ s/($Foswiki::regex{setVarRegex})/
148 $text =~
149s/^($Foswiki::regex{setRegex})($Foswiki::regex{tagNameRegex})\s*\=(.*$(?:\n[ \t]+[^\s*].*$)*)/
150 $1._saveSet($query, $web, $topic, $3, $4, $formDef)/mgeo;
151 Foswiki::Func::saveTopic( $web, $topic, $meta, $text );
152 }
153 Foswiki::Func::setTopicEditLock( $web, $topic, 0 );
154
155 # Finish with a redirect so that the *new* values are seen
156 my $viewUrl = Foswiki::Func::getScriptUrl( $web, $topic, 'view' );
157 Foswiki::Func::redirectCgiQuery( undef, $viewUrl );
158 return;
159 }
160
161 # implicit action="view", or drop through from "save" or "cancel"
162 $_[0] =~ s/%EDITPREFERENCES({.*?})?%/_generateEditButton($web, $topic)/ge;
163}
164
165# Use the post-rendering handler to plug our formatted editor units
166# into the text
167
# spent 141µs (94+47) within Foswiki::Plugins::PreferencesPlugin::postRenderingHandler which was called 5 times, avg 28µs/call: # 5 times (94µs+47µs) by Foswiki::Plugin::invoke at line 287 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Plugin.pm, avg 28µs/call
sub postRenderingHandler {
168 ### my ( $text ) = @_;
169
1705127µs1047µs $_[0] =~ s/SHELTER$MARKER(\d+)/$shelter[$1]/g;
# spent 28µs making 5 calls to Foswiki::Plugins::PreferencesPlugin::CORE:subst, avg 6µs/call # spent 19µs making 5 calls to Foswiki::Plugins::PreferencesPlugin::CORE:regcomp, avg 4µs/call
171}
172
173# Pluck the default value of a named field from a form definition
174sub _getField {
175 my ( $formDef, $name ) = @_;
176 foreach my $f ( @{ $formDef->{fields} } ) {
177 if ( $f->{name} eq $name ) {
178 return $f;
179 }
180 }
181 return;
182}
183
184# Generate a field suitable for editing this type. Use of the core
185# function 'renderFieldForEdit' ensures that we will pick up
186# extra edit types defined in other plugins.
187sub _generateEditField {
188 my ( $web, $topic, $name, $value, $formDef ) = @_;
189 $value =~ s/^\s*(.*?)\s*$/$1/ge;
190
191 my ( $extras, $html );
192
193 if ($formDef) {
194 my $fieldDef = $formDef->getField($name);
195 if ($fieldDef) {
196 my ($topicObject) = Foswiki::Func::readTopic( $web, $topic );
197 ( $extras, $html ) =
198 $fieldDef->renderForEdit( $topicObject, $value );
199 }
200 }
201 unless ($html) {
202
203 if ( $value =~ /\n/ ) {
204 my $rows = 1;
205 $rows++ while $value =~ /\n/g;
206
207 # No form definition and there are newlines, default to textarea
208 $html = CGI::textarea(
209 -class => 'foswikiAlert foswikiInputField',
210 -name => $name,
211 -cols => 80,
212 -rows => $rows,
213 -default => $value
214 );
215 }
216 else {
217
218 # No form definition and no newlines, default to text field.
219 $html = CGI::textfield(
220 -class => 'foswikiAlert foswikiInputField',
221 -name => $name,
222 -size => 80,
223 -value => $value
224 );
225 }
226 }
227
228 push( @shelter, $html );
229
230 return $START_MARKER
231 . CGI::span(
232 {
233 class => 'foswikiAlert',
234 style => 'font-weight:bold;'
235 },
236 $name . ' = SHELTER' . $MARKER . $#shelter
237 ) . $END_MARKER;
238}
239
240# Generate the button that replaces the EDITPREFERENCES tag in view mode
241sub _generateEditButton {
242 my ( $web, $topic ) = @_;
243
244 my $viewUrl = Foswiki::Func::getScriptUrl( $web, $topic, 'viewauth' );
245 my $text = CGI::start_form(
246 -name => 'editpreferences',
247 -method => 'post',
248 -action => $viewUrl
249 );
250 $text .= CGI::input(
251 {
252 type => 'hidden',
253 name => 'prefsaction',
254 value => 'edit'
255 }
256 );
257 $text .= CGI::submit(
258 -name => 'edit',
259 -value => 'Edit Preferences',
260 -class => 'foswikiButton'
261 );
262 $text .= CGI::end_form();
263 $text =~ s/\n//sg;
264 return $text;
265}
266
267# Generate the buttons that replace the EDITPREFERENCES tag in edit mode
268sub _generateControlButtons {
269 my ( $web, $topic ) = @_;
270
271 my $text = $START_MARKER
272 . CGI::submit(
273 -name => 'prefsaction',
274 -value => 'Save new settings',
275 -class => 'foswikiSubmit',
276 -accesskey => 's'
277 );
278 $text .= '&nbsp;';
279 $text .= CGI::submit(
280 -name => 'prefsaction',
281 -value => 'Cancel',
282 -class => 'foswikiButtonCancel',
283 -accesskey => 'c'
284 ) . $END_MARKER;
285 return $text;
286}
287
288# Given a Set in the topic being saved, look in the query to see
289# if there is a new value for the Set and generate a new
290# Set statement.
291sub _saveSet {
292 my ( $query, $web, $topic, $name, $value, $formDef ) = @_;
293
294 my $newValue = $query->param($name);
295 if ( not defined $newValue ) {
296 $newValue = $value;
297 $newValue =~ s/^\s+//; # strip leading whitespace
298 }
299
300 if ($formDef) {
301 my $fieldDef = _getField( $formDef, $name );
302 my $type = $fieldDef->{type} || '';
303 if ( $type && $type =~ /^checkbox/ ) {
304 my $val = '';
305 my $vals = $fieldDef->{value};
306 foreach my $item (@$vals) {
307 my $cvalue = $query->param( $name . $item );
308 if ( defined($cvalue) ) {
309 if ( !$val ) {
310 $val = '';
311 }
312 else {
313 $val .= ', ' if ($cvalue);
314 }
315 $val .= $item if ($cvalue);
316 }
317 }
318 $newValue = $val;
319 }
320 }
321
322 # if no form def, it's just treated as text
323
324 return $name . ' = ' . $newValue;
325}
326
32719µs1;
328__END__
 
# spent 2.36ms within Foswiki::Plugins::PreferencesPlugin::CORE:match which was called 1131 times, avg 2µs/call: # 1131 times (2.36ms+0s) by Foswiki::Plugins::PreferencesPlugin::beforeCommonTagsHandler at line 64, avg 2µs/call
sub Foswiki::Plugins::PreferencesPlugin::CORE:match; # opcode
# spent 19µs within Foswiki::Plugins::PreferencesPlugin::CORE:regcomp which was called 5 times, avg 4µs/call: # 5 times (19µs+0s) by Foswiki::Plugins::PreferencesPlugin::postRenderingHandler at line 170, avg 4µs/call
sub Foswiki::Plugins::PreferencesPlugin::CORE:regcomp; # opcode
# spent 28µs within Foswiki::Plugins::PreferencesPlugin::CORE:subst which was called 5 times, avg 6µs/call: # 5 times (28µs+0s) by Foswiki::Plugins::PreferencesPlugin::postRenderingHandler at line 170, avg 6µs/call
sub Foswiki::Plugins::PreferencesPlugin::CORE:subst; # opcode