← 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:58 2011

Filename/usr/local/src/github.com/foswiki/core/lib/Foswiki/Plugins/CommentPlugin/Comment.pm
StatementsExecuted 77 statements in 3.66ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
111456µs437msFoswiki::Plugins::CommentPlugin::Comment::::promptFoswiki::Plugins::CommentPlugin::Comment::prompt
31140µs40µsFoswiki::Plugins::CommentPlugin::Comment::::_expandPromptParamsFoswiki::Plugins::CommentPlugin::Comment::_expandPromptParams
55138µs38µsFoswiki::Plugins::CommentPlugin::Comment::::CORE:substFoswiki::Plugins::CommentPlugin::Comment::CORE:subst (opcode)
11136µs45µsFoswiki::Plugins::CommentPlugin::::BEGIN@5 Foswiki::Plugins::CommentPlugin::BEGIN@5
72129µs29µsFoswiki::Plugins::CommentPlugin::Comment::::CORE:substcontFoswiki::Plugins::CommentPlugin::Comment::CORE:substcont (opcode)
11126µs78µsFoswiki::Plugins::CommentPlugin::::BEGIN@7.52 Foswiki::Plugins::CommentPlugin::BEGIN@7.52
11123µs23µsFoswiki::Plugins::CommentPlugin::::BEGIN@12.55 Foswiki::Plugins::CommentPlugin::BEGIN@12.55
11118µs215µsFoswiki::Plugins::CommentPlugin::::BEGIN@14 Foswiki::Plugins::CommentPlugin::BEGIN@14
11118µs42µsFoswiki::Plugins::CommentPlugin::::BEGIN@6 Foswiki::Plugins::CommentPlugin::BEGIN@6
11118µs410µsFoswiki::Plugins::CommentPlugin::::BEGIN@8.53 Foswiki::Plugins::CommentPlugin::BEGIN@8.53
11115µs15µsFoswiki::Plugins::CommentPlugin::::BEGIN@10.54 Foswiki::Plugins::CommentPlugin::BEGIN@10.54
11113µs13µsFoswiki::Plugins::CommentPlugin::::BEGIN@11 Foswiki::Plugins::CommentPlugin::BEGIN@11
1114µs4µsFoswiki::Plugins::CommentPlugin::Comment::::CORE:matchFoswiki::Plugins::CommentPlugin::Comment::CORE:match (opcode)
0000s0sFoswiki::Plugins::CommentPlugin::Comment::::_alertFoswiki::Plugins::CommentPlugin::Comment::_alert
0000s0sFoswiki::Plugins::CommentPlugin::Comment::::_nthFoswiki::Plugins::CommentPlugin::Comment::_nth
0000s0sFoswiki::Plugins::CommentPlugin::Comment::::_remove_nthFoswiki::Plugins::CommentPlugin::Comment::_remove_nth
0000s0sFoswiki::Plugins::CommentPlugin::Comment::::saveFoswiki::Plugins::CommentPlugin::Comment::save
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#
3# This version is specific to Foswiki::Plugins::VERSION > 1.026
4
5252µs254µs
# spent 45µs (36+9) within Foswiki::Plugins::CommentPlugin::BEGIN@5 which was called: # once (36µs+9µs) by Foswiki::Plugins::CommentPlugin::_COMMENT at line 5
use strict;
# spent 45µs making 1 call to Foswiki::Plugins::CommentPlugin::BEGIN@5 # spent 9µs making 1 call to strict::import
6248µs266µs
# spent 42µs (18+24) within Foswiki::Plugins::CommentPlugin::BEGIN@6 which was called: # once (18µs+24µs) by Foswiki::Plugins::CommentPlugin::_COMMENT at line 6
use warnings;
# spent 42µs making 1 call to Foswiki::Plugins::CommentPlugin::BEGIN@6 # spent 24µs making 1 call to warnings::import
7259µs2130µs
# spent 78µs (26+52) within Foswiki::Plugins::CommentPlugin::BEGIN@7.52 which was called: # once (26µs+52µs) by Foswiki::Plugins::CommentPlugin::_COMMENT at line 7
use Assert;
# spent 78µs making 1 call to Foswiki::Plugins::CommentPlugin::BEGIN@7.52 # spent 52µs making 1 call to Assert::import
8254µs2801µs
# spent 410µs (18+392) within Foswiki::Plugins::CommentPlugin::BEGIN@8.53 which was called: # once (18µs+392µs) by Foswiki::Plugins::CommentPlugin::_COMMENT at line 8
use Error ':try';
# spent 410µs making 1 call to Foswiki::Plugins::CommentPlugin::BEGIN@8.53 # spent 392µs making 1 call to Error::import
9
10246µs115µs
# spent 15µs within Foswiki::Plugins::CommentPlugin::BEGIN@10.54 which was called: # once (15µs+0s) by Foswiki::Plugins::CommentPlugin::_COMMENT at line 10
use Foswiki;
# spent 15µs making 1 call to Foswiki::Plugins::CommentPlugin::BEGIN@10.54
11245µs113µs
# spent 13µs within Foswiki::Plugins::CommentPlugin::BEGIN@11 which was called: # once (13µs+0s) by Foswiki::Plugins::CommentPlugin::_COMMENT at line 11
use Foswiki::Plugins;
# spent 13µs making 1 call to Foswiki::Plugins::CommentPlugin::BEGIN@11
12261µs123µs
# spent 23µs within Foswiki::Plugins::CommentPlugin::BEGIN@12.55 which was called: # once (23µs+0s) by Foswiki::Plugins::CommentPlugin::_COMMENT at line 12
use Foswiki::Store;
# spent 23µs making 1 call to Foswiki::Plugins::CommentPlugin::BEGIN@12.55
13
1422.81ms2412µs
# spent 215µs (18+197) within Foswiki::Plugins::CommentPlugin::BEGIN@14 which was called: # once (18µs+197µs) by Foswiki::Plugins::CommentPlugin::_COMMENT at line 14
use CGI qw( -any );
# spent 215µs making 1 call to Foswiki::Plugins::CommentPlugin::BEGIN@14 # spent 197µs making 1 call to CGI::import
15
16package Foswiki::Plugins::CommentPlugin::Comment;
17
18# PUBLIC STATIC convert COMMENT statements to form prompts
19
# spent 437ms (456µs+437) within Foswiki::Plugins::CommentPlugin::Comment::prompt which was called: # once (456µs+437ms) by Foswiki::Plugins::CommentPlugin::_COMMENT at line 80 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Plugins/CommentPlugin.pm
sub prompt {
2022213µs my ( $attrs, $web, $topic, $disabled ) = @_;
21
221111µs my $type =
# spent 111µs making 1 call to Foswiki::Func::getPreferencesValue
23 $attrs->{type}
24 || $attrs->{mode}
25 || Foswiki::Func::getPreferencesValue('COMMENTPLUGIN_DEFAULT_TYPE')
26 || 'above';
27
28 my $templatetopic;
29 if ( $attrs->{templatetopic} ) {
30 my ( $templocweb, $temploctopic ) =
31 Foswiki::Func::normalizeWebTopicName( $web, $attrs->{templatetopic} );
32 $templatetopic = "$templocweb.$temploctopic";
33 }
34
35 # Get the templates.
36181µs my $templateFile =
# spent 81µs making 1 call to Foswiki::Func::getPreferencesValue
37 $templatetopic
38 || Foswiki::Func::getPreferencesValue('COMMENTPLUGIN_TEMPLATES')
39 || 'comments';
40
411430ms unless ( Foswiki::Func::loadTemplate($templateFile) ) {
# spent 430ms making 1 call to Foswiki::Func::loadTemplate
42 Foswiki::Func::writeWarning(
43 "Could not read template file '$templateFile'");
44 return _alert("Could not read templates from '$templateFile'");
45 }
46
47 my $message = $attrs->{default} || '';
48 $message = $disabled if $disabled;
49
50 # clean off whitespace
5115µs $type =~ s/\s+//;
52
53 # Expand the template in the context of the web where the comment
54 # box is (not the target of the comment!)
551626µs my $input = Foswiki::Func::expandTemplate("PROMPT:$type");
# spent 626µs making 1 call to Foswiki::Func::expandTemplate
56 return _alert("No such template def 'PROMPT:$type'")
57 unless ( defined($input) && $input ne '' );
58
59 # Expand special attributes as required
60320µs870µs $input =~ s/%([a-z]\w+)\|(.*?)%/_expandPromptParams($1, $2, $attrs)/ieg;
# spent 40µs making 3 calls to Foswiki::Plugins::CommentPlugin::Comment::_expandPromptParams, avg 13µs/call # spent 20µs making 4 calls to Foswiki::Plugins::CommentPlugin::Comment::CORE:substcont, avg 5µs/call # spent 11µs making 1 call to Foswiki::Plugins::CommentPlugin::Comment::CORE:subst
61
62 # see if this comment is targeted at a different topic, and
63 # change the url if it is.
64 my $anchor = undef;
65 my $target = $attrs->{target};
66 if ($target) {
67
68 # extract web and anchor
69 if ( $target =~ s/^(\w+)\.// ) {
70 $web = $1;
71 }
72 if ( $target =~ s/(#\w+)$// ) {
73 $anchor = $1;
74 }
75 if ( $target ne '' ) {
76 $topic = $target;
77 }
78 }
79
80 # Build the endpoint before we munge the web and topic
81 my $endPoint = "$web.$topic";
82
83 # See if a save url has been defined in the template
841219µs my $url = Foswiki::Func::expandTemplate('save_url');
# spent 219µs making 1 call to Foswiki::Func::expandTemplate
85
86 # Default it to a rest url if not
871230µs $url ||= Foswiki::Func::getScriptUrl( 'CommentPlugin', 'comment', 'rest' );
# spent 230µs making 1 call to Foswiki::Func::getScriptUrl
88
89 $url = '' if $disabled;
90
91 my $noform = $attrs->{noform} || '';
92
93 # Note: Item10050: If CommentPlugin prompt adds newlines then it prevents
94 # COMMENT inside TML tables so avoid cosmetic \n
95676µs14µs if ( $input !~ m/^%RED%/ ) {
9623µs420µs $input =~ s/%DISABLED%/$disabled ? 'disabled' : '' /ge;
# spent 10µs making 1 call to Foswiki::Plugins::CommentPlugin::Comment::CORE:subst # spent 10µs making 3 calls to Foswiki::Plugins::CommentPlugin::Comment::CORE:substcont, avg 3µs/call
9716µs $input =~ s/%MESSAGE%/$message/g;
98 my $idx = $attrs->{comment_index};
99
1001170µs unless ($disabled) {
101 my $hiddenFields = "";
1021587µs $hiddenFields .=
# spent 587µs making 1 call to CGI::AUTOLOAD
103 CGI::hidden( -name => 'topic', -value => "$web.$topic" );
104
1051449µs $hiddenFields .=
# spent 449µs making 1 call to CGI::hidden
106 CGI::hidden( -name => 'comment_action', -value => 'save' );
107
1081421µs $hiddenFields .=
# spent 421µs making 1 call to CGI::hidden
109 CGI::hidden( -name => 'endPoint', -value => $endPoint );
110
1111416µs $hiddenFields .=
# spent 416µs making 1 call to CGI::hidden
112 CGI::hidden( -name => 'comment_type', -value => $type );
113
114 if ( defined( $attrs->{nonotify} ) ) {
115 $hiddenFields .=
116 CGI::hidden( -name => 'comment_nonotify', value => 1 );
117 }
118 if ($templatetopic) {
119 $hiddenFields .= CGI::hidden(
120 -name => 'comment_templatetopic',
121 -value => $templatetopic
122 );
123 }
12418µs if ( $attrs->{location} ) {
125 $hiddenFields .= CGI::hidden(
126 -name => 'comment_location',
127 -value => $attrs->{location}
128 );
129 }
130 elsif ($anchor) {
131 $hiddenFields .=
132 CGI::hidden( -name => 'comment_anchor', -value => $anchor );
133 }
134 else {
1351419µs $hiddenFields .=
# spent 419µs making 1 call to CGI::hidden
136 CGI::hidden( -name => 'comment_index', -value => $idx );
137 }
138 if ( $attrs->{nopost} ) {
139 $hiddenFields .= CGI::hidden(
140 -name => 'comment_nopost',
141 -value => $attrs->{nopost}
142 );
143 }
144 if ( $attrs->{remove} ) {
145 $hiddenFields .=
146 CGI::hidden( -name => 'comment_remove', -value => $idx );
147 }
148 $input .= $hiddenFields;
149 }
150
151 # SMELL: would have been more elegant to split this into
152 # FORM:head:type and FORM:tail:type. Too late now :-(
1531238µs my $form = Foswiki::Func::expandTemplate("FORM:$type");
# spent 238µs making 1 call to Foswiki::Func::expandTemplate
154
155344µs if ( $noform || $form ) {
156 if ($form) {
157 $form =~ s/%COMMENTPROMPT%/$input/;
158 $input = $form;
159 }
160 else {
161 $input = "$form $input";
162 }
163 }
164 else {
1651392µs my $startform = CGI::start_form(
# spent 392µs making 1 call to CGI::AUTOLOAD
166 -name => $type . $idx,
167 -id => $type . $idx,
168 -action => $url,
169 -method => 'post'
170 );
171
172 # Item10050: CGI may add a trailing new line.
173 # This prevents using COMMENT inside TML tables
17417µs $startform =~ s/\n$//;
175
1761254µs $input = $startform . $input . CGI::end_form();
# spent 254µs making 1 call to CGI::AUTOLOAD
177 }
178 }
179 return $input;
180}
181
182sub _alert {
183 my $mess = shift;
184 return "<span class='foswikiAlert'> $mess </span>";
185}
186
187# PRIVATE expand special %param|default% parameters in PROMPT template
188
# spent 40µs within Foswiki::Plugins::CommentPlugin::Comment::_expandPromptParams which was called 3 times, avg 13µs/call: # 3 times (40µs+0s) by Foswiki::Plugins::CommentPlugin::Comment::prompt at line 60, avg 13µs/call
sub _expandPromptParams {
1891242µs my ( $name, $default, $attrs ) = @_;
190
191 my $val = $attrs->{$name};
192 return $val if defined($val);
193 return $default;
194}
195
196# PUBLIC build new topic text
197sub save {
198
199 my ( $text, $web, $topic ) = @_;
200
201 my $wikiName = Foswiki::Func::getWikiName();
202 my $mode = $Foswiki::cfg{Plugins}{CommentPlugin}{RequiredForSave}
203 || 'change';
204 my $access =
205 Foswiki::Func::checkAccessPermission( $mode, $wikiName, $text, $topic,
206 $web );
207 unless ($access) {
208
209 # user has no permission to change the topic
210 throw Foswiki::AccessControlException(
211 $mode,
212 $wikiName,
213 web => $web,
214 topic => $topic,
215 ''
216 );
217 }
218
219 my $query = Foswiki::Func::getCgiQuery();
220 return unless $query;
221
222 # The type of the comment dictates where in the target topic it
223 # will be saved.
224 my $type =
225 $query->param('comment_type')
226 || Foswiki::Func::getPreferencesValue('COMMENTPLUGIN_DEFAULT_TYPE')
227 || 'above';
228
229 # Indexing comment instances depends on macro expansion
230 # inside-out-left-right order and INCLUDE and SECTION expansion
231 # being correctly handled. Only relevant if the comment is being
232 # inserted relative to the instance, of course.
233 my $index = $query->param('comment_index') || 0;
234
235 my $anchor = $query->param('comment_anchor');
236 my $location = $query->param('comment_location');
237 my $remove = $query->param('comment_remove');
238 my $nopost = $query->param('comment_nopost');
239 my $templatetopic = $query->param('comment_templatetopic');
240
241 if ($templatetopic) {
242 my ( $templocweb, $temploctopic ) =
243 Foswiki::Func::normalizeWebTopicName( $web, $templatetopic );
244 $templatetopic = "$templocweb.$temploctopic";
245 }
246
247 # Get the templates.
248 my $templateFile =
249 $templatetopic
250 || Foswiki::Func::getPreferencesValue('COMMENTPLUGIN_TEMPLATES')
251 || 'comments';
252
253 Foswiki::Func::loadTemplate($templateFile);
254
255 my $output = Foswiki::Func::expandTemplate("OUTPUT:$type");
256 die _alert("No such template def 'OUTPUT:$type'") unless $output;
257
258 # Expand the template
259 my $position = 'AFTER';
260 if ( $output =~ s/%POS:(.*?)%//g ) {
261 $position = $1;
262 }
263
264 # Expand common variables in the template, but don't expand other
265 # tags.
266 $output = Foswiki::Func::expandVariablesOnTopicCreation($output);
267
268 $output = '' unless defined($output);
269
270 # SMELL: Reverse the process that inserts meta-data just performed
271 # by the Foswiki core, but this time without the support of the
272 # methods in the core. Fortunately this will work even if there is
273 # no embedded meta-data.
274 my $premeta = '';
275 my $postmeta = '';
276 my $inpost = 0;
277 my $innerText = '';
278 foreach my $line ( split( /\r?\n/, $text ) ) {
279 if ( $line =~ /^%META:[A-Z]+{[^}]*}%$/ ) {
280 if ($inpost) {
281 $postmeta .= $line . "\n";
282 }
283 else {
284 $premeta .= $line . "\n";
285 }
286 }
287 else {
288 $innerText .= $line . "\n";
289 $inpost = 1;
290 }
291 }
292 $text = $innerText;
293
294 #make sure the anchor or location exits
295 if ( defined($location) and not( $text =~ /(?<!location\=\")($location)/ ) )
296 {
297 undef $location;
298 }
299 if ( defined($anchor) and $text !~ /^$anchor\s*$/m ) {
300 undef $anchor;
301 }
302
303 unless ($nopost) {
304 if ( $position eq 'TOP' ) {
305 $text = $output . $text;
306 }
307 elsif ( $position eq 'BOTTOM' ) {
308
309 # Awkward newlines here, to avoid running into meta-data.
310 # This should _not_ be a problem.
311 $text =~ s/[\r\n]+$//;
312 $text .= "\n" unless $output =~ m/^\n/s;
313 $text .= $output;
314 $text .= "\n" unless $text =~ m/\n$/s;
315 }
316 else {
317 if ($location) {
318 if ( $position eq 'BEFORE' ) {
319 $text .= $output
320 unless (
321 $text =~ s/(?<!location\=\")($location)/$output$1/m );
322 }
323 else { # AFTER
324 $text .= $output
325 unless (
326 $text =~ s/(?<!location\=\")($location)/$1$output/m );
327
328 }
329 $text .= "\n" unless $text =~ m/\n$/s;
330 }
331 elsif ($anchor) {
332
333 # position relative to anchor
334 if ( $position eq 'BEFORE' ) {
335 $text .= $output
336 unless ( $text =~ s/^($anchor\s)/$output$1/m );
337 }
338 else { # AFTER
339 $text .= $output
340 unless ( $text =~ s/^($anchor\s)/$1$output/m );
341 }
342 $text .= "\n" unless $text =~ m/\n$/s;
343 }
344 else {
345
346 # Position relative to index'th comment
347 my $idx = 0;
348 unless (
349 $text =~ s((%COMMENT({.*?})?%.*\n))
350 (&_nth($1,\$idx,$position,$index,$output))eg
351 )
352 {
353
354 # If there was a problem adding relative to the comment,
355 # add to the end of the topic
356 $text .= $output;
357 }
358 $text .= "\n" unless $text =~ m/\n$/s;
359 }
360 }
361 }
362
363 if ( defined $remove ) {
364
365 # remove the index'th comment box
366 my $idx = 0;
367 $text =~ s/(%COMMENT({.*?})?%)/_remove_nth($1,\$idx,$remove)/eg;
368 }
369
370 return $premeta . $text . $postmeta;
371}
372
373# PRIVATE embed output if this comment is the interesting one
374sub _nth {
375 my ( $tag, $pidx, $position, $index, $output ) = @_;
376
377 if ( $$pidx == $index ) {
378 if ( $position eq 'BEFORE' ) {
379 $tag = $output . $tag;
380 }
381 else { # AFTER
382 $tag .= $output;
383 }
384 }
385 $$pidx++;
386 return $tag;
387}
388
389# PRIVATE remove the nth comment box
390sub _remove_nth {
391 my ( $tag, $pidx, $index ) = @_;
392 $tag = '' if ( $$pidx == $index );
393 $$pidx++;
394 return $tag;
395}
396
39716µs1;
398__END__
 
# spent 4µs within Foswiki::Plugins::CommentPlugin::Comment::CORE:match which was called: # once (4µs+0s) by Foswiki::Plugins::CommentPlugin::Comment::prompt at line 95
sub Foswiki::Plugins::CommentPlugin::Comment::CORE:match; # opcode
# spent 38µs within Foswiki::Plugins::CommentPlugin::Comment::CORE:subst which was called 5 times, avg 8µs/call: # once (11µs+0s) by Foswiki::Plugins::CommentPlugin::Comment::prompt at line 60 # once (10µs+0s) by Foswiki::Plugins::CommentPlugin::Comment::prompt at line 96 # once (7µs+0s) by Foswiki::Plugins::CommentPlugin::Comment::prompt at line 174 # once (6µs+0s) by Foswiki::Plugins::CommentPlugin::Comment::prompt at line 97 # once (5µs+0s) by Foswiki::Plugins::CommentPlugin::Comment::prompt at line 51
sub Foswiki::Plugins::CommentPlugin::Comment::CORE:subst; # opcode
# spent 29µs within Foswiki::Plugins::CommentPlugin::Comment::CORE:substcont which was called 7 times, avg 4µs/call: # 4 times (20µs+0s) by Foswiki::Plugins::CommentPlugin::Comment::prompt at line 60, avg 5µs/call # 3 times (10µs+0s) by Foswiki::Plugins::CommentPlugin::Comment::prompt at line 96, avg 3µs/call
sub Foswiki::Plugins::CommentPlugin::Comment::CORE:substcont; # opcode