← Index
NYTProf Performance Profile   « line view »
For ./view
  Run on Fri Jul 31 19:05:14 2015
Reported on Fri Jul 31 19:08:10 2015

Filename/var/www/foswiki11/lib/Foswiki/Plugins/CommentPlugin/Comment.pm
StatementsExecuted 15 statements in 2.16ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
11118µs32µsFoswiki::Plugins::CommentPlugin::::BEGIN@5 Foswiki::Plugins::CommentPlugin::BEGIN@5
11112µs12µsFoswiki::Plugins::CommentPlugin::::BEGIN@10.52 Foswiki::Plugins::CommentPlugin::BEGIN@10.52
11111µs99µsFoswiki::Plugins::CommentPlugin::::BEGIN@12 Foswiki::Plugins::CommentPlugin::BEGIN@12
11110µs16µsFoswiki::Plugins::CommentPlugin::::BEGIN@6 Foswiki::Plugins::CommentPlugin::BEGIN@6
1119µs9µsFoswiki::Plugins::CommentPlugin::::BEGIN@11.53 Foswiki::Plugins::CommentPlugin::BEGIN@11.53
1118µs8µsFoswiki::Plugins::CommentPlugin::::BEGIN@8.51 Foswiki::Plugins::CommentPlugin::BEGIN@8.51
1117µs7µsFoswiki::Plugins::CommentPlugin::::BEGIN@9 Foswiki::Plugins::CommentPlugin::BEGIN@9
0000s0sFoswiki::Plugins::CommentPlugin::Comment::::_buildNewTopicFoswiki::Plugins::CommentPlugin::Comment::_buildNewTopic
0000s0sFoswiki::Plugins::CommentPlugin::Comment::::_expandPromptParamsFoswiki::Plugins::CommentPlugin::Comment::_expandPromptParams
0000s0sFoswiki::Plugins::CommentPlugin::Comment::::_getTemplateFoswiki::Plugins::CommentPlugin::Comment::_getTemplate
0000s0sFoswiki::Plugins::CommentPlugin::Comment::::_getTemplateLocationFoswiki::Plugins::CommentPlugin::Comment::_getTemplateLocation
0000s0sFoswiki::Plugins::CommentPlugin::Comment::::_handleInputFoswiki::Plugins::CommentPlugin::Comment::_handleInput
0000s0sFoswiki::Plugins::CommentPlugin::Comment::::_nthFoswiki::Plugins::CommentPlugin::Comment::_nth
0000s0sFoswiki::Plugins::CommentPlugin::Comment::::_remove_nthFoswiki::Plugins::CommentPlugin::Comment::_remove_nth
0000s0sFoswiki::Plugins::CommentPlugin::Comment::::promptFoswiki::Plugins::CommentPlugin::Comment::prompt
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
5233µs246µs
# spent 32µs (18+14) within Foswiki::Plugins::CommentPlugin::BEGIN@5 which was called: # once (18µs+14µs) by Foswiki::Plugins::CommentPlugin::commonTagsHandler at line 5
use strict;
# spent 32µs making 1 call to Foswiki::Plugins::CommentPlugin::BEGIN@5 # spent 14µs making 1 call to strict::import
6231µs222µs
# spent 16µs (10+6) within Foswiki::Plugins::CommentPlugin::BEGIN@6 which was called: # once (10µs+6µs) by Foswiki::Plugins::CommentPlugin::commonTagsHandler at line 6
use warnings;
# spent 16µs making 1 call to Foswiki::Plugins::CommentPlugin::BEGIN@6 # spent 6µs making 1 call to warnings::import
7
8226µs18µs
# spent 8µs within Foswiki::Plugins::CommentPlugin::BEGIN@8.51 which was called: # once (8µs+0s) by Foswiki::Plugins::CommentPlugin::commonTagsHandler at line 8
use Foswiki;
# spent 8µs making 1 call to Foswiki::Plugins::CommentPlugin::BEGIN@8.51
9228µs17µs
# spent 7µs within Foswiki::Plugins::CommentPlugin::BEGIN@9 which was called: # once (7µs+0s) by Foswiki::Plugins::CommentPlugin::commonTagsHandler at line 9
use Foswiki::Plugins;
# spent 7µs making 1 call to Foswiki::Plugins::CommentPlugin::BEGIN@9
10231µs112µs
# spent 12µs within Foswiki::Plugins::CommentPlugin::BEGIN@10.52 which was called: # once (12µs+0s) by Foswiki::Plugins::CommentPlugin::commonTagsHandler at line 10
use Foswiki::Store;
# spent 12µs making 1 call to Foswiki::Plugins::CommentPlugin::BEGIN@10.52
11231µs19µs
# spent 9µs within Foswiki::Plugins::CommentPlugin::BEGIN@11.53 which was called: # once (9µs+0s) by Foswiki::Plugins::CommentPlugin::commonTagsHandler at line 11
use Foswiki::Attrs;
# spent 9µs making 1 call to Foswiki::Plugins::CommentPlugin::BEGIN@11.53
1221.98ms2186µs
# spent 99µs (11+87) within Foswiki::Plugins::CommentPlugin::BEGIN@12 which was called: # once (11µs+87µs) by Foswiki::Plugins::CommentPlugin::commonTagsHandler at line 12
use CGI qw( -any );
# spent 99µs making 1 call to Foswiki::Plugins::CommentPlugin::BEGIN@12 # spent 87µs making 1 call to CGI::import
13
14package Foswiki::Plugins::CommentPlugin::Comment;
15
16# PUBLIC save the given comment.
17sub save {
18
19 #my ( $text, $topic, $web ) = @_;
20
21 my $wikiName = Foswiki::Func::getWikiName();
22 if (
23 !Foswiki::Func::checkAccessPermission(
24 'change', $wikiName, '', $_[1], $_[2]
25 )
26 )
27 {
28
29 # user has no permission to change the topic
30 throw Foswiki::OopsException(
31 'accessdenied',
32 def => 'topic_access',
33 web => $_[2],
34 topic => $_[1]
35 );
36 }
37 else {
38 _buildNewTopic(@_);
39 }
40}
41
42# PUBLIC STATIC convert COMMENT statements to form prompts
43sub prompt {
44
45 #my ( $previewing, $text, $web, $topic ) = @_;
46
47 my $defaultType =
48 Foswiki::Func::getPreferencesValue('COMMENTPLUGIN_DEFAULT_TYPE')
49 || 'above';
50
51 my $message = '';
52
53 # Is commenting disabled?
54 my $disable = '';
55 if ( $_[0] ) {
56
57 # We are in Preview mode
58 $message = "(Edit - Preview)";
59 $disable = 'disabled';
60 }
61 elsif ( Foswiki::Func::getContext->{static} ) {
62 $message = "(Static view)";
63 $disable = 'disabled';
64 }
65
66 my $idx = 0;
67 $_[1] =~
68s/%COMMENT({.*?})?%/_handleInput($1,$_[2],$_[3],\$idx,$message,$disable,$defaultType)/eg;
69}
70
71=pod
72
73Parses a templatetopic attribute and returns a "Web.Topic" string.
74
75=cut
76
77sub _getTemplateLocation {
78 my ( $attrtemplatetopic, $web ) = @_;
79
80 my $templatetopic = '';
81 my $templateweb = $web || '';
82 if ($attrtemplatetopic) {
83 my ( $templocweb, $temploctopic ) =
84 Foswiki::Func::normalizeWebTopicName( $templateweb,
85 $attrtemplatetopic );
86 $templatetopic = "$templocweb.$temploctopic";
87 }
88 return $templatetopic;
89}
90
91# PRIVATE generate an input form for a %COMMENT tag
92sub _handleInput {
93 my ( $attributes, $web, $topic, $pidx, $message, $disable, $defaultType ) =
94 @_;
95
96 $attributes =~ s/^{(.*)}$/$1/ if ($attributes);
97
98 my $attrs = new Foswiki::Attrs( $attributes, 1 );
99 my $type = $attrs->remove('type') || $attrs->remove('mode') || $defaultType;
100 my $silent = $attrs->remove('nonotify');
101 my $location = $attrs->remove('location');
102 my $remove = $attrs->remove('remove');
103 my $nopost = $attrs->remove('nopost');
104 my $default = $attrs->remove('default');
105 my $attrtemplatetopic = $attrs->remove('templatetopic') || '';
106 my $templatetopic = _getTemplateLocation( $attrtemplatetopic, $web );
107
108 $message ||= $default || '';
109 $message ||= $default || '';
110 $disable ||= '';
111
112 # clean off whitespace
113 $type =~ m/(\S*)/;
114 $type = $1;
115
116 # Expand the template in the context of the web where the comment
117 # box is (not the target of the comment!)
118 my $input = _getTemplate( "PROMPT:$type", $web, $topic, $templatetopic )
119 || '';
120 return $input if $input =~ m/^%RED%/so;
121
122 # Expand special attributes as required
123 $input =~ s/%([a-z]\w+)\|(.*?)%/_expandPromptParams($1, $2, $attrs)/ieg;
124
125 # see if this comment is targeted at a different topic, and
126 # change the url if it is.
127 my $anchor = undef;
128 my $target = $attrs->remove('target');
129 if ($target) {
130
131 # extract web and anchor
132 if ( $target =~ s/^(\w+)\.// ) {
133 $web = $1;
134 }
135 if ( $target =~ s/(#\w+)$// ) {
136 $anchor = $1;
137 }
138 if ( $target ne '' ) {
139 $topic = $target;
140 }
141 }
142
143 my $url = '';
144 if ( $disable eq '' ) {
145 $url = Foswiki::Func::getScriptUrl( $web, $topic, 'save' );
146 }
147
148 # Note: Item10050: If CommentPlugin prompt adds newlines then it prevents
149 # COMMENT inside TML tables so avoid cosmetic \n
150 my $noform = $attrs->remove('noform') || '';
151 if ( $input !~ m/^%RED%/ ) {
152 $input =~ s/%DISABLED%/$disable/g;
153 $input =~ s/%MESSAGE%/$message/g;
154 my $n = $$pidx + 0;
155
156 if ( $disable eq '' ) {
157 my $hiddenFields = "";
158 $hiddenFields .=
159 CGI::hidden( -name => 'comment_action', -value => 'save' );
160 $hiddenFields .=
161 CGI::hidden( -name => 'comment_type', -value => $type );
162 if ( defined($silent) ) {
163 $hiddenFields .=
164 CGI::hidden( -name => 'comment_nonotify', value => 1 );
165 }
166 if ($templatetopic) {
167 $hiddenFields .= CGI::hidden(
168 -name => 'comment_templatetopic',
169 -value => $templatetopic
170 );
171 }
172 if ($location) {
173 $hiddenFields .= CGI::hidden(
174 -name => 'comment_location',
175 -value => $location
176 );
177 }
178 elsif ($anchor) {
179 $hiddenFields .=
180 CGI::hidden( -name => 'comment_anchor', -value => $anchor );
181 }
182 else {
183 $hiddenFields .=
184 CGI::hidden( -name => 'comment_index', -value => $$pidx );
185 }
186 if ($nopost) {
187 $hiddenFields .=
188 CGI::hidden( -name => 'comment_nopost', -value => $nopost );
189 }
190 if ($remove) {
191 $hiddenFields .=
192 CGI::hidden( -name => 'comment_remove', -value => $$pidx );
193 }
194 $input .= $hiddenFields;
195 }
196 if ($noform) {
197 my $form =
198 _getTemplate( "FORM:$type", $topic, $web, $templatetopic, 'off' )
199 || '';
200 if ($form) {
201 $form =~ s/%COMMENTPROMPT%/$input/;
202 $input = $form;
203 }
204 }
205 unless ( $noform eq 'on' ) {
206 my $startform = CGI::start_form(
207 -name => $type . $n,
208 -id => $type . $n,
209 -action => $url,
210 -method => 'post'
211 );
212
213 # Item10050: CGI may add a trailing new line.
214 # This prevents using COMMENT inside TML tables
215 $startform =~ s/\n$//;
216
217 $input = $startform . $input . CGI::end_form();
218 }
219 }
220 $$pidx++;
221 return $input;
222}
223
224# PRIVATE get the given template and do standard expansions
225sub _getTemplate {
226 my ( $name, $topic, $web, $templatetopic, $warn ) = @_;
227
228 $warn ||= '';
229
230 # Get the templates.
231 my $templateFile =
232 $templatetopic
233 || Foswiki::Func::getPreferencesValue('COMMENTPLUGIN_TEMPLATES')
234 || 'comments';
235
236 my $templates = Foswiki::Func::loadTemplate($templateFile);
237 if ( !$templates ) {
238 Foswiki::Func::writeWarning(
239 "Could not read template file '$templateFile'");
240 return;
241 }
242
243 my $t = Foswiki::Func::expandTemplate($name);
244 return "%RED%No such template def TMPL:DEF{$name}%ENDCOLOR%"
245 unless ( defined($t) && $t ne '' ) || $warn eq 'off';
246
247 return $t;
248}
249
250# PRIVATE expand special %param|default% parameters in PROMPT template
251sub _expandPromptParams {
252 my ( $name, $default, $attrs ) = @_;
253
254 my $val = $attrs->{$name};
255 return $val if defined($val);
256 return $default;
257}
258
259# PRIVATE STATIC Performs comment insertion in the topic.
260sub _buildNewTopic {
261
262 #my ( $text, $topic, $web ) = @_;
263 my ( $topic, $web ) = ( $_[1], $_[2] );
264
265 my $query = Foswiki::Func::getCgiQuery();
266 return unless $query;
267
268 my $type =
269 $query->param('comment_type')
270 || Foswiki::Func::getPreferencesValue('COMMENTPLUGIN_DEFAULT_TYPE')
271 || 'above';
272 my $index = $query->param('comment_index') || 0;
273 my $anchor = $query->param('comment_anchor');
274 my $location = $query->param('comment_location');
275 my $remove = $query->param('comment_remove');
276 my $nopost = $query->param('comment_nopost');
277 my $templatetopic = $query->param('comment_templatetopic') || '';
278
279 my $output = _getTemplate( "OUTPUT:$type", $topic, $web, $templatetopic );
280 if ( $output =~ m/^%RED%/ ) {
281 die $output;
282 }
283
284 # Expand the template
285 my $position = 'AFTER';
286 if ( $output =~ s/%POS:(.*?)%//g ) {
287 $position = $1;
288 }
289
290 # Expand common variables in the template, but don't expand other
291 # tags.
292 $output = Foswiki::Func::expandVariablesOnTopicCreation($output);
293
294 $output = '' unless defined($output);
295
296 # SMELL: Reverse the process that inserts meta-data just performed
297 # by the Foswiki core, but this time without the support of the
298 # methods in the core. Fortunately this will work even if there is
299 # no embedded meta-data.
300 # Note: because this is Dakar, and has sensible semantics for handling
301 # the =text= parameter to =save=, there is no longer any need to re-read
302 # the topic. The text is automatically defaulted to the existing topic
303 # text if the =text= parameter isn't specified - which for comments,
304 # it isn't.
305 my $premeta = '';
306 my $postmeta = '';
307 my $inpost = 0;
308 my $text = '';
309 foreach my $line ( split( /\r?\n/, $_[0] ) ) {
310 if ( $line =~ /^%META:[A-Z]+{[^}]*}%/ ) {
311 if ($inpost) {
312 $postmeta .= $line . "\n";
313 }
314 else {
315 $premeta .= $line . "\n";
316 }
317 }
318 else {
319 $text .= $line . "\n";
320 $inpost = 1;
321 }
322 }
323
324 #make sure the anchor or location exits
325 if ( defined($location) and not( $text =~ /(?<!location\=\")($location)/ ) )
326 {
327 undef $location;
328 }
329 if ( defined($anchor) and $text !~ /^$anchor\s*$/m ) {
330 undef $anchor;
331 }
332
333 unless ($nopost) {
334 if ( $position eq 'TOP' ) {
335 $text = $output . $text;
336 }
337 elsif ( $position eq 'BOTTOM' ) {
338
339 # Awkward newlines here, to avoid running into meta-data.
340 # This should _not_ be a problem.
341 $text =~ s/[\r\n]+$//;
342 $text .= "\n" unless $output =~ m/^\n/s;
343 $text .= $output;
344 $text .= "\n" unless $text =~ m/\n$/s;
345 }
346 else {
347 if ($location) {
348 if ( $position eq 'BEFORE' ) {
349 $text .= $output
350 unless (
351 $text =~ s/(?<!location\=\")($location)/$output$1/m );
352 }
353 else { # AFTER
354 $text .= $output
355 unless (
356 $text =~ s/(?<!location\=\")($location)/$1$output/m );
357
358 }
359 $text .= "\n" unless $text =~ m/\n$/s;
360 }
361 elsif ($anchor) {
362
363 # position relative to anchor
364 if ( $position eq 'BEFORE' ) {
365 $text .= $output
366 unless ( $text =~ s/^($anchor\s)/$output$1/m );
367 }
368 else { # AFTER
369 $text .= $output
370 unless ( $text =~ s/^($anchor\s)/$1$output/m );
371 }
372 $text .= "\n" unless $text =~ m/\n$/s;
373 }
374 else {
375
376 # Position relative to index'th comment
377 my $idx = 0;
378 unless (
379 $text =~ s((%COMMENT({.*?})?%.*\n))
380 (&_nth($1,\$idx,$position,$index,$output))eg
381 )
382 {
383
384 # If there was a problem adding relative to the comment,
385 # add to the end of the topic
386 $text .= $output;
387 }
388 $text .= "\n" unless $text =~ m/\n$/s;
389 }
390 }
391 }
392
393 if ( defined $remove ) {
394
395 # remove the index'th comment box
396 my $idx = 0;
397 $text =~ s/(%COMMENT({.*?})?%)/_remove_nth($1,\$idx,$remove)/eg;
398 }
399
400 $_[0] = $premeta . $text . $postmeta;
401}
402
403# PRIVATE embed output if this comment is the interesting one
404sub _nth {
405 my ( $tag, $pidx, $position, $index, $output ) = @_;
406
407 if ( $$pidx == $index ) {
408 if ( $position eq 'BEFORE' ) {
409 $tag = $output . $tag;
410 }
411 else { # AFTER
412 $tag .= $output;
413 }
414 }
415 $$pidx++;
416 return $tag;
417}
418
419# PRIVATE remove the nth comment box
420sub _remove_nth {
421 my ( $tag, $pidx, $index ) = @_;
422 $tag = '' if ( $$pidx == $index );
423 $$pidx++;
424 return $tag;
425}
426
42713µs1;
428__END__