Filename | /var/www/foswikidev/core/lib/Foswiki/Plugins/CommentPlugin.pm |
Statements | Executed 25 statements in 1.16ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
1 | 1 | 1 | 25µs | 552µs | initPlugin | Foswiki::Plugins::CommentPlugin::
1 | 1 | 1 | 14µs | 28µs | BEGIN@7 | Foswiki::Plugins::CommentPlugin::
1 | 1 | 1 | 11µs | 11µs | BEGIN@13 | Foswiki::Plugins::CommentPlugin::
1 | 1 | 1 | 10µs | 121µs | BEGIN@10 | Foswiki::Plugins::CommentPlugin::
1 | 1 | 1 | 10µs | 14µs | BEGIN@8 | Foswiki::Plugins::CommentPlugin::
1 | 1 | 1 | 10µs | 40µs | BEGIN@9 | Foswiki::Plugins::CommentPlugin::
1 | 1 | 1 | 4µs | 4µs | BEGIN@12 | Foswiki::Plugins::CommentPlugin::
0 | 0 | 0 | 0s | 0s | _COMMENT | Foswiki::Plugins::CommentPlugin::
0 | 0 | 0 | 0s | 0s | __ANON__[:237] | Foswiki::Plugins::CommentPlugin::
0 | 0 | 0 | 0s | 0s | __ANON__[:247] | Foswiki::Plugins::CommentPlugin::
0 | 0 | 0 | 0s | 0s | __ANON__[:258] | Foswiki::Plugins::CommentPlugin::
0 | 0 | 0 | 0s | 0s | __ANON__[:269] | Foswiki::Plugins::CommentPlugin::
0 | 0 | 0 | 0s | 0s | _restSave | Foswiki::Plugins::CommentPlugin::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | # See bottom of file for license and copyright information | ||||
2 | # | ||||
3 | # See Plugin topic for history and plugin information | ||||
4 | |||||
5 | package Foswiki::Plugins::CommentPlugin; | ||||
6 | |||||
7 | 2 | 29µs | 2 | 42µs | # spent 28µs (14+14) within Foswiki::Plugins::CommentPlugin::BEGIN@7 which was called:
# once (14µs+14µs) by Foswiki::Plugin::BEGIN@2.7 at line 7 # spent 28µs making 1 call to Foswiki::Plugins::CommentPlugin::BEGIN@7
# spent 14µs making 1 call to strict::import |
8 | 2 | 24µs | 2 | 19µs | # spent 14µs (10+5) within Foswiki::Plugins::CommentPlugin::BEGIN@8 which was called:
# once (10µs+5µs) by Foswiki::Plugin::BEGIN@2.7 at line 8 # spent 14µs making 1 call to Foswiki::Plugins::CommentPlugin::BEGIN@8
# spent 5µs making 1 call to warnings::import |
9 | 2 | 31µs | 2 | 70µs | # spent 40µs (10+30) within Foswiki::Plugins::CommentPlugin::BEGIN@9 which was called:
# once (10µs+30µs) by Foswiki::Plugin::BEGIN@2.7 at line 9 # spent 40µs making 1 call to Foswiki::Plugins::CommentPlugin::BEGIN@9
# spent 30µs making 1 call to Exporter::import |
10 | 2 | 31µs | 2 | 231µs | # spent 121µs (10+111) within Foswiki::Plugins::CommentPlugin::BEGIN@10 which was called:
# once (10µs+111µs) by Foswiki::Plugin::BEGIN@2.7 at line 10 # spent 121µs making 1 call to Foswiki::Plugins::CommentPlugin::BEGIN@10
# spent 111µs making 1 call to Error::import |
11 | |||||
12 | 2 | 27µs | 1 | 4µs | # spent 4µs within Foswiki::Plugins::CommentPlugin::BEGIN@12 which was called:
# once (4µs+0s) by Foswiki::Plugin::BEGIN@2.7 at line 12 # spent 4µs making 1 call to Foswiki::Plugins::CommentPlugin::BEGIN@12 |
13 | 2 | 994µs | 1 | 11µs | # spent 11µs within Foswiki::Plugins::CommentPlugin::BEGIN@13 which was called:
# once (11µs+0s) by Foswiki::Plugin::BEGIN@2.7 at line 13 # spent 11µs making 1 call to Foswiki::Plugins::CommentPlugin::BEGIN@13 |
14 | |||||
15 | # Please use major.minor | ||||
16 | 1 | 800ns | our $VERSION = '2.6'; | ||
17 | 1 | 200ns | our $RELEASE = '24 Jul 2015'; | ||
18 | 1 | 200ns | our $SHORTDESCRIPTION = | ||
19 | 'Quickly post comments to a page without an edit/save cycle'; | ||||
20 | 1 | 200ns | our $NO_PREFS_IN_TOPIC = 1; | ||
21 | |||||
22 | # Reset when the plugin is reset, this counter counts the instances of the | ||||
23 | # %COMMENT macro and indexes them. | ||||
24 | 1 | 100ns | our $commentIndex; | ||
25 | |||||
26 | # spent 552µs (25+528) within Foswiki::Plugins::CommentPlugin::initPlugin which was called:
# once (25µs+528µs) by Foswiki::Plugin::__ANON__[/var/www/foswikidev/core/lib/Foswiki/Plugin.pm:257] at line 250 of /var/www/foswikidev/core/lib/Foswiki/Plugin.pm | ||||
27 | |||||
28 | 1 | 2µs | my ( $topic, $web, $user, $installWeb ) = @_; | ||
29 | 1 | 800ns | $commentIndex = 0; | ||
30 | |||||
31 | 1 | 2µs | 1 | 15µs | Foswiki::Func::registerTagHandler( 'COMMENT', \&_COMMENT ); # spent 15µs making 1 call to Foswiki::Func::registerTagHandler |
32 | 1 | 5µs | 1 | 20µs | Foswiki::Func::registerRESTHandler( # spent 20µs making 1 call to Foswiki::Func::registerRESTHandler |
33 | 'comment', \&_restSave, | ||||
34 | |||||
35 | validate => 1, | ||||
36 | authenticate => $Foswiki::cfg{Plugins}{CommentPlugin}{GuestCanComment} | ||||
37 | ? 0 | ||||
38 | : 1, | ||||
39 | http_allow => 'POST' | ||||
40 | ); | ||||
41 | |||||
42 | 1 | 3µs | 1 | 21µs | Foswiki::Plugins::JQueryPlugin::registerPlugin( 'Comment', # spent 21µs making 1 call to Foswiki::Plugins::JQueryPlugin::registerPlugin |
43 | 'Foswiki::Plugins::CommentPlugin::JQuery' ); | ||||
44 | 1 | 3µs | 1 | 471µs | unless ( # spent 471µs making 1 call to Foswiki::Plugins::JQueryPlugin::createPlugin |
45 | Foswiki::Plugins::JQueryPlugin::createPlugin( | ||||
46 | "Comment", $Foswiki::Plugins::SESSION | ||||
47 | ) | ||||
48 | ) | ||||
49 | { | ||||
50 | die 'Failed to register JQuery plugin'; | ||||
51 | } | ||||
52 | |||||
53 | if ( (DEBUG) | ||||
54 | && $web eq $Foswiki::cfg{SystemWebName} | ||||
55 | && $topic eq 'InstalledPlugins' ) | ||||
56 | { | ||||
57 | |||||
58 | # Compilation check | ||||
59 | require Foswiki::Plugins::CommentPlugin::Comment; | ||||
60 | } | ||||
61 | 1 | 4µs | return 1; | ||
62 | } | ||||
63 | |||||
64 | sub _COMMENT { | ||||
65 | my ( $session, $params, $topic, $web ) = @_; | ||||
66 | |||||
67 | # Indexing each macro instance | ||||
68 | $params->{comment_index} = $commentIndex++; | ||||
69 | |||||
70 | # Check the context has 'view' script | ||||
71 | my $context = Foswiki::Func::getContext(); | ||||
72 | my $disabled = ''; | ||||
73 | |||||
74 | if ( $context->{command_line} ) { | ||||
75 | $disabled = Foswiki::Func::expandCommonVariables( | ||||
76 | '%MAKETEXT{"Commenting is disabled while running from the command line"}%' | ||||
77 | ); | ||||
78 | } | ||||
79 | elsif ( $context->{static} ) { | ||||
80 | $disabled = Foswiki::Func::expandCommonVariables( | ||||
81 | '%MAKETEXT{"Commenting is disabled for static viewing"}%'); | ||||
82 | } | ||||
83 | elsif ( !$context->{view} ) { | ||||
84 | $disabled = Foswiki::Func::expandCommonVariables( | ||||
85 | '%MAKETEXT{"Commenting is disabled when not in view context"}%'); | ||||
86 | } | ||||
87 | elsif ( | ||||
88 | !( | ||||
89 | $Foswiki::cfg{Plugins}{CommentPlugin}{GuestCanComment} | ||||
90 | || $context->{authenticated} | ||||
91 | ) | ||||
92 | ) | ||||
93 | { | ||||
94 | $disabled = Foswiki::Func::expandCommonVariables( | ||||
95 | '%MAKETEXT{"Commenting is disabled while not logged in"}%'); | ||||
96 | } | ||||
97 | |||||
98 | require Foswiki::Plugins::CommentPlugin::Comment; | ||||
99 | |||||
100 | Foswiki::Plugins::CommentPlugin::Comment::prompt( $params, $web, $topic, | ||||
101 | $disabled ); | ||||
102 | } | ||||
103 | |||||
104 | # REST handler for save operator. We use a REST handler because we need | ||||
105 | # to be able to bypass the permissions checking that the save script | ||||
106 | # would do. We handle the return in several different ways; first, if | ||||
107 | # everything is OK, we set a 200 status and drop back to allow any | ||||
108 | # redirectto to be handled. Second, if we get an exception, and the | ||||
109 | # request came from AJAX, we return a 500 status. If the | ||||
110 | # parameter is not set, we pass the exception on to the UI package. | ||||
111 | |||||
112 | sub _restSave { | ||||
113 | my $session = shift; | ||||
114 | my $response = $session->{response}; | ||||
115 | my $query = Foswiki::Func::getCgiQuery(); | ||||
116 | |||||
117 | my ( $web, $topic ) = | ||||
118 | Foswiki::Func::normalizeWebTopicName( undef, | ||||
119 | scalar( $query->param('topic') ) ); | ||||
120 | |||||
121 | if ( $query->param('comment_target') ) { | ||||
122 | ( $web, $topic ) = | ||||
123 | Foswiki::Func::normalizeWebTopicName( $web, | ||||
124 | scalar( $query->param('comment_target') ) ); | ||||
125 | } | ||||
126 | |||||
127 | $web = | ||||
128 | Foswiki::Sandbox::untaint( $web, \&Foswiki::Sandbox::validateWebName ); | ||||
129 | |||||
130 | unless ( Foswiki::Func::webExists($web) ) { | ||||
131 | if ( $query->header('X-Requested-With') eq 'XMLHttpRequest' ) { | ||||
132 | $response->header( -status => 500 ); | ||||
133 | $response->print("No such web '$web'"); | ||||
134 | } | ||||
135 | else { | ||||
136 | throw Foswiki::OopsException( | ||||
137 | 'oopsattention', | ||||
138 | status => 403, | ||||
139 | def => 'web_not_found', | ||||
140 | params => [ $web, "$web.$topic" ] | ||||
141 | ); | ||||
142 | } | ||||
143 | } | ||||
144 | |||||
145 | # Note: missing topic is okay, will be created if allowed. | ||||
146 | # but it needs to be a valid name. | ||||
147 | |||||
148 | my $origTopic = $topic; # (Stash topic name in case it's bad) | ||||
149 | $topic = Foswiki::Sandbox::untaint( $topic, | ||||
150 | \&Foswiki::Sandbox::validateTopicName ); | ||||
151 | |||||
152 | unless ($topic) { | ||||
153 | |||||
154 | # validation failed - illegal name, don't have a topic name | ||||
155 | if ( $query->header('X-Requested-With') eq 'XMLHttpRequest' ) { | ||||
156 | $response->header( -status => 500 ); | ||||
157 | $response->print("No such topic '$topic'"); | ||||
158 | } | ||||
159 | else { | ||||
160 | throw Foswiki::OopsException( | ||||
161 | 'oopsattention', | ||||
162 | status => 403, | ||||
163 | def => 'invalid_topic_parameter', | ||||
164 | params => [ "$origTopic", 'comment_target' ] | ||||
165 | ); | ||||
166 | } | ||||
167 | } | ||||
168 | |||||
169 | my $isXHR = | ||||
170 | ( ( $query->header('X-Requested-With') || '' ) eq 'XMLHttpRequest' ); | ||||
171 | |||||
172 | try { | ||||
173 | require Foswiki::Plugins::CommentPlugin::Comment; | ||||
174 | |||||
175 | # The save function does access control checking | ||||
176 | my ( $meta, $text, $position, $output ) = | ||||
177 | Foswiki::Plugins::CommentPlugin::Comment::comment( $query, $web, | ||||
178 | $topic ); | ||||
179 | |||||
180 | $response->header( -status => 200 ); | ||||
181 | if ( defined $meta ) { | ||||
182 | |||||
183 | # Don't save anything if nothing to save | ||||
184 | Foswiki::Func::saveTopic( $web, $topic, $meta, $text, | ||||
185 | { ignorepermissions => 1 } ); | ||||
186 | |||||
187 | if ($isXHR) { | ||||
188 | $response->pushHeader( 'X-Foswiki-Comment' => $position ); | ||||
189 | |||||
190 | # Add new validation key to HTTP header | ||||
191 | if ( $Foswiki::cfg{Validation}{Method} eq 'strikeone' ) { | ||||
192 | require Foswiki::Validation; | ||||
193 | my $context = | ||||
194 | $query->url( -full => 1, -path => 1, -query => 1 ) | ||||
195 | . time(); | ||||
196 | my $cgis = $session->getCGISession(); | ||||
197 | my $nonce; | ||||
198 | if ( Foswiki::Validation->can('generateValidationKey') ) { | ||||
199 | $nonce = | ||||
200 | Foswiki::Validation::generateValidationKey( $cgis, | ||||
201 | $context, 1 ); | ||||
202 | } | ||||
203 | else { | ||||
204 | # Pre 2.0 compatibility | ||||
205 | my $html = Foswiki::Validation::addValidationKey( $cgis, | ||||
206 | $context, 1 ); | ||||
207 | $nonce = $1 if ( $html =~ m/value=['"]\?(.*?)['"]/ ); | ||||
208 | } | ||||
209 | $response->pushHeader( 'X-Foswiki-Validation' => $nonce ) | ||||
210 | if defined $nonce; | ||||
211 | } | ||||
212 | |||||
213 | # Decorate the response to show it's been ajax-added. | ||||
214 | # It's TML, and free format, so there's a limit as to | ||||
215 | # how clever we can be. | ||||
216 | my $pht = $session->i18n->maketext( | ||||
217 | 'This is a temporary placeholder for your new comment. Refresh the topic to see the actual comment.' | ||||
218 | ); | ||||
219 | $output = | ||||
220 | '<div class="comment_placeholder" ' | ||||
221 | . "title=\"$pht\">\n" | ||||
222 | . $output | ||||
223 | . "\n</div>"; | ||||
224 | my $comment = | ||||
225 | Foswiki::Func::expandCommonVariables( | ||||
226 | Foswiki::Func::renderText( $output, $web, $topic ) ); | ||||
227 | $response->print($comment); | ||||
228 | } | ||||
229 | } | ||||
230 | |||||
231 | if ( !$isXHR && !$query->param('redirectto') ) { | ||||
232 | |||||
233 | # Not XHR; Default to redirect to view if redirectto not given | ||||
234 | $query->param( 'redirectto' => | ||||
235 | Foswiki::Func::getScriptUrl( $web, $topic, 'view' ) ); | ||||
236 | } | ||||
237 | } | ||||
238 | catch Foswiki::AccessControlException with { | ||||
239 | my $e = shift; | ||||
240 | if ($isXHR) { | ||||
241 | $response->header( -status => 404 ); | ||||
242 | $response->print( $e->stringify ); | ||||
243 | } | ||||
244 | else { | ||||
245 | $e->throw(); | ||||
246 | } | ||||
247 | } | ||||
248 | catch Error::Simple with { | ||||
249 | my $e = shift; | ||||
250 | |||||
251 | # Redirect already requested to clear the endpoint | ||||
252 | if ( $e =~ 'restauth-redirect' ) { | ||||
253 | $query->param( redirectto => '' ); | ||||
254 | } | ||||
255 | else { | ||||
256 | $e->throw(); | ||||
257 | } | ||||
258 | } | ||||
259 | otherwise { | ||||
260 | my $e = shift; | ||||
261 | |||||
262 | if ($isXHR) { | ||||
263 | $response->header( -status => 500 ); | ||||
264 | $response->print($e); | ||||
265 | } | ||||
266 | else { | ||||
267 | $e->throw(); | ||||
268 | } | ||||
269 | }; | ||||
270 | return undef; | ||||
271 | } | ||||
272 | |||||
273 | 1 | 4µs | 1; | ||
274 | __END__ |