← 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/SubscribePlugin.pm
StatementsExecuted 100 statements in 1.64ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
2113.35ms91.9msFoswiki::Plugins::SubscribePlugin::::_SUBSCRIBEFoswiki::Plugins::SubscribePlugin::_SUBSCRIBE
21152µs2.36msFoswiki::Plugins::SubscribePlugin::::_template_textFoswiki::Plugins::SubscribePlugin::_template_text
21139µs532µsFoswiki::Plugins::SubscribePlugin::::_getNonceFoswiki::Plugins::SubscribePlugin::_getNonce
11135µs109µsFoswiki::Plugins::SubscribePlugin::::initPluginFoswiki::Plugins::SubscribePlugin::initPlugin
11114µs27µsFoswiki::Plugins::SubscribePlugin::::BEGIN@14Foswiki::Plugins::SubscribePlugin::BEGIN@14
11112µs130µsFoswiki::Plugins::SubscribePlugin::::BEGIN@18Foswiki::Plugins::SubscribePlugin::BEGIN@18
11110µs36µsFoswiki::Plugins::SubscribePlugin::::BEGIN@17Foswiki::Plugins::SubscribePlugin::BEGIN@17
1114µs4µsFoswiki::Plugins::SubscribePlugin::::BEGIN@19Foswiki::Plugins::SubscribePlugin::BEGIN@19
1114µs4µsFoswiki::Plugins::SubscribePlugin::::BEGIN@16Foswiki::Plugins::SubscribePlugin::BEGIN@16
1114µs4µsFoswiki::Plugins::SubscribePlugin::::BEGIN@15Foswiki::Plugins::SubscribePlugin::BEGIN@15
0000s0sFoswiki::Plugins::SubscribePlugin::::__ANON__[:245]Foswiki::Plugins::SubscribePlugin::__ANON__[:245]
0000s0sFoswiki::Plugins::SubscribePlugin::::__ANON__[:249]Foswiki::Plugins::SubscribePlugin::__ANON__[:249]
0000s0sFoswiki::Plugins::SubscribePlugin::::_rest_subscribeFoswiki::Plugins::SubscribePlugin::_rest_subscribe
0000s0sFoswiki::Plugins::SubscribePlugin::::_subscribeFoswiki::Plugins::SubscribePlugin::_subscribe
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1# See the bottom of the file for description, copyright and license information
2package Foswiki::Plugins::SubscribePlugin;
3
4=begin TML
5
6This plugin supports a subscription button that, when embedded in a topic,
7will add the clicker to the WebNotify for that topic. It uses the API
8published by the MailerContrib to manage the subscriptions in WebNotify.
9
10WikiGuest cannot be subscribed, only logged-in users.
11
12=cut
13
14227µs241µs
# spent 27µs (14+14) within Foswiki::Plugins::SubscribePlugin::BEGIN@14 which was called: # once (14µs+14µs) by Foswiki::Plugin::BEGIN@2.36 at line 14
use strict;
# spent 27µs making 1 call to Foswiki::Plugins::SubscribePlugin::BEGIN@14 # spent 14µs making 1 call to strict::import
15220µs14µs
# spent 4µs within Foswiki::Plugins::SubscribePlugin::BEGIN@15 which was called: # once (4µs+0s) by Foswiki::Plugin::BEGIN@2.36 at line 15
use Foswiki::Func ();
# spent 4µs making 1 call to Foswiki::Plugins::SubscribePlugin::BEGIN@15
16223µs14µs
# spent 4µs within Foswiki::Plugins::SubscribePlugin::BEGIN@16 which was called: # once (4µs+0s) by Foswiki::Plugin::BEGIN@2.36 at line 16
use Foswiki::Plugins::JQueryPlugin ();
# spent 4µs making 1 call to Foswiki::Plugins::SubscribePlugin::BEGIN@16
17228µs263µs
# spent 36µs (10+26) within Foswiki::Plugins::SubscribePlugin::BEGIN@17 which was called: # once (10µs+26µs) by Foswiki::Plugin::BEGIN@2.36 at line 17
use Assert;
# spent 36µs making 1 call to Foswiki::Plugins::SubscribePlugin::BEGIN@17 # spent 26µs making 1 call to Exporter::import
18230µs2248µs
# spent 130µs (12+118) within Foswiki::Plugins::SubscribePlugin::BEGIN@18 which was called: # once (12µs+118µs) by Foswiki::Plugin::BEGIN@2.36 at line 18
use Error ':try';
# spent 130µs making 1 call to Foswiki::Plugins::SubscribePlugin::BEGIN@18 # spent 118µs making 1 call to Error::import
1921.20ms14µs
# spent 4µs within Foswiki::Plugins::SubscribePlugin::BEGIN@19 which was called: # once (4µs+0s) by Foswiki::Plugin::BEGIN@2.36 at line 19
use JSON ();
# spent 4µs making 1 call to Foswiki::Plugins::SubscribePlugin::BEGIN@19
20
211600nsour $VERSION = '3.4';
221200nsour $RELEASE = '27 Jul 2015';
231400nsour $SHORTDESCRIPTION =
24'This is a companion plugin to the MailerContrib. It allows you to trivially add a "Subscribe me" link to topics to get subscribed to changes.';
251200nsour $NO_PREFS_IN_TOPIC = 1;
26
271100nsour $tmpls;
28
29
# spent 109µs (35+74) within Foswiki::Plugins::SubscribePlugin::initPlugin which was called: # once (35µs+74µ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
sub initPlugin {
3011µs my ( $TOPIC, $WEB ) = @_;
31
3212µs11µs Foswiki::Func::getContext()->{'SubscribePluginAllowed'} = 1;
# spent 1µs making 1 call to Foswiki::Func::getContext
33
34 # LocalSite.cfg takes precedence. Give admin most control.
3513µs123µs my $activeWebs = $Foswiki::cfg{Plugins}{SubscribePlugin}{ActiveWebs}
# spent 23µs making 1 call to Foswiki::Func::getPreferencesValue
36 || Foswiki::Func::getPreferencesValue("SUBSCRIBEPLUGIN_ACTIVEWEBS");
37
381700ns if ($activeWebs) {
39 $activeWebs =~ s/\s*\,\s*/\|/g; # Change comma's to "or"
40 $activeWebs =~ s/^\s*//; # Drop leading spaces
41 $activeWebs =~ s/\s*$//; # Drop trailing spaces
42 #$activeWebs =~ s/[^[:alnum:]\|]//g
43 # ; # Filter any characters not valid in WikiWords
44 Foswiki::Func::getContext()->{'SubscribePluginAllowed'} = 0
45 unless ( $WEB =~ qr/^($activeWebs)$/ );
46 }
47
48 # No subscribe links for pages rendered for static applications (PDF)
4912µs11µs Foswiki::Func::getContext()->{'SubscribePluginAllowed'} = 0
# spent 1µs making 1 call to Foswiki::Func::getContext
50 if ( Foswiki::Func::getContext()->{'static'} );
51
5212µs116µs Foswiki::Func::registerTagHandler( 'SUBSCRIBE', \&_SUBSCRIBE );
# spent 16µs making 1 call to Foswiki::Func::registerTagHandler
5313µs121µs Foswiki::Func::registerRESTHandler(
# spent 21µs making 1 call to Foswiki::Func::registerRESTHandler
54 'subscribe', \&_rest_subscribe,
55 authenticate => 1,
56 validate => 1,
57 http_allow => 'POST'
58 );
59
6012µs112µs Foswiki::Plugins::JQueryPlugin::registerPlugin( 'Subscribe',
# spent 12µs making 1 call to Foswiki::Plugins::JQueryPlugin::registerPlugin
61 'Foswiki::Plugins::SubscribePlugin::JQuery' );
62
6311µs undef $tmpls;
6414µs return 1;
65}
66
67# Show a button inviting (un)subscription to this topic
68
# spent 91.9ms (3.35+88.5) within Foswiki::Plugins::SubscribePlugin::_SUBSCRIBE which was called 2 times, avg 45.9ms/call: # 2 times (3.35ms+88.5ms) by Foswiki::Func::__ANON__[/var/www/foswikidev/core/lib/Foswiki/Func.pm:662] at line 660 of /var/www/foswikidev/core/lib/Foswiki/Func.pm, avg 45.9ms/call
sub _SUBSCRIBE {
6923µs my ( $session, $params, $topic, $web ) = @_;
70
7124µs23µs return ''
# spent 3µs making 2 calls to Foswiki::Func::getContext, avg 1µs/call
72 unless ( Foswiki::Func::getContext()->{'SubscribePluginAllowed'} );
73
7425µs241µs my $cur_user = Foswiki::Func::getWikiName();
# spent 41µs making 2 calls to Foswiki::Func::getWikiName, avg 20µs/call
7522µs my $who = $params->{who} || $cur_user;
7622µs my $render = $params->{render} || 'text'; # Rendering icon or text link
77
78 # Guest user cannot subscribe
7922µs return '' if ( $who eq $Foswiki::cfg{DefaultUserWikiName} );
80
812700ns if ( defined $params->{topic} ) {
82 ( $web, $topic ) =
83 Foswiki::Func::normalizeWebTopicName( $web, $params->{topic} );
84 }
85287µs require Foswiki::Contrib::MailerContrib;
86210µs274.8ms my $unsubscribe =
# spent 74.8ms making 2 calls to Foswiki::Contrib::MailerContrib::isSubscribedTo, avg 37.4ms/call
87 ( $params->{unsubscribe}
88 || Foswiki::Contrib::MailerContrib::isSubscribedTo( $web, $who,
89 $topic ) ) ? 1 : 0;
9024µs219µs my $doUnsubscribe = Foswiki::isTrue($unsubscribe);
# spent 19µs making 2 calls to Foswiki::isTrue, avg 10µs/call
91
92210µs22.36ms my $tmpl =
# spent 2.36ms making 2 calls to Foswiki::Plugins::SubscribePlugin::_template_text, avg 1.18ms/call
93 _template_text( ( $doUnsubscribe ? 'un' : '' ) . 'subscribe', $render );
94
9527µs411µs my $action =
# spent 8µs making 2 calls to Foswiki::I18N::Fallback::maketext, avg 4µs/call # spent 4µs making 2 calls to Foswiki::i18n, avg 2µs/call
96 $session->i18n->maketext( $doUnsubscribe ? "Unsubscribe" : "Subscribe" );
97
9825µs $tmpl =~ s/\$action/$action/g;
99212µs $tmpl =~ s/\$topic/$web.$topic/g;
100211µs $tmpl =~ s/\$(subscriber|wikiname)/$who/g;
10127µs $tmpl =~ s/\$remove/$unsubscribe/g;
102215µs2532µs $tmpl =~ s/\$nonce/_getNonce($session)/ge;
# spent 532µs making 2 calls to Foswiki::Plugins::SubscribePlugin::_getNonce, avg 266µs/call
103
10429µs22.09ms Foswiki::Plugins::JQueryPlugin::createPlugin("subscribe");
# spent 2.09ms making 2 calls to Foswiki::Plugins::JQueryPlugin::createPlugin, avg 1.05ms/call
105
10628µs return $tmpl;
107}
108
109# subscribe_topic (topic is used if subscribe_topic is missing)
110# subscribe_subscriber (current user is used if missing)
111# unsubscribe (will unsubscribe if true, subscribe otherwise)
112sub _rest_subscribe {
113 my ( $session, $plugin, $verb, $response ) = @_;
114 my $query = Foswiki::Func::getCgiQuery();
115
116 ASSERT($query) if DEBUG;
117
118 my $cur_user = Foswiki::Func::getWikiName();
119 my $text = '';
120 my $status = 200;
121 my $isSubs = 0;
122
123 # We have been asked to subscribe
124 my $topics = $query->param('topic');
125 unless ($topics) {
126 $status = 400;
127 $text = _template_text('no_subscribe_topic');
128 }
129 else {
130 $topics =~ m/^(.*)$/;
131 $topics = $1; # Untaint - we will check it later
132 my ( $web, $topic ) =
133 Foswiki::Func::normalizeWebTopicName( undef, $topics );
134 my $who = $query->param('subscriber');
135 $who ||= $cur_user;
136 if ( $who eq $Foswiki::cfg{DefaultUserWikiName} ) {
137 $status = 400;
138 $text = _template_text('cannot_subscribe');
139 }
140 else {
141 my $unsubscribe = $query->param('remove');
142 ( $text, $status ) =
143 _subscribe( $web, $topic, $who, $cur_user, $unsubscribe );
144 $isSubs =
145 Foswiki::Contrib::MailerContrib::isSubscribedTo( $web, $who,
146 $topic );
147 }
148 }
149
150 $response->header(
151 -status => $status,
152 -type => 'text/json',
153 -charset => 'UTF-8'
154 );
155
156 # Add new validation key to HTTP header
157 if ( $Foswiki::cfg{Validation}{Method} eq 'strikeone' ) {
158 my $nonce = _getNonce($session);
159 $response->pushHeader( 'X-Foswiki-Validation' => $nonce )
160 if defined $nonce;
161 }
162
163 $response->print(
164 JSON::to_json(
165 {
166 message => $text,
167 remove => ( $isSubs ? 1 : 0 )
168 }
169 )
170 );
171
172 return undef;
173}
174
175
# spent 532µs (39+493) within Foswiki::Plugins::SubscribePlugin::_getNonce which was called 2 times, avg 266µs/call: # 2 times (39µs+493µs) by Foswiki::Plugins::SubscribePlugin::_SUBSCRIBE at line 102, avg 266µs/call
sub _getNonce {
17622µs my ($session) = @_;
17723µs require Foswiki::Validation;
17824µs214µs my $query = Foswiki::Func::getCgiQuery();
# spent 14µs making 2 calls to Foswiki::Func::getCgiQuery, avg 7µs/call
179214µs2442µs my $context = $query->url( -full => 1, -path => 1, -query => 1 ) . time();
# spent 442µs making 2 calls to Foswiki::Request::url, avg 221µs/call
18026µs237µs my $cgis = $session->getCGISession();
# spent 37µs making 2 calls to Foswiki::getCGISession, avg 18µs/call
18127µs return '' unless $cgis;
182 if ( Foswiki::Validation->can('generateValidationKey') ) {
183 return Foswiki::Validation::generateValidationKey( $cgis, $context, 1 );
184 }
185 else {
186 # Pre 2.0 compatibility
187 my $html = Foswiki::Validation::addValidationKey( $cgis, $context, 1 );
188 return $1 if ( $html =~ m/value=['"]\?(.*?)['"]/ );
189 die "Internal Error";
190 }
191}
192
193
# spent 2.36ms (52µs+2.30) within Foswiki::Plugins::SubscribePlugin::_template_text which was called 2 times, avg 1.18ms/call: # 2 times (52µs+2.30ms) by Foswiki::Plugins::SubscribePlugin::_SUBSCRIBE at line 92, avg 1.18ms/call
sub _template_text {
1942900ns my $def = shift;
19521µs my $t = '';
196
19727µs if ( $_[0] && $_[0] =~ m/^(text|icon)$/ ) {
198 $t = substr( $_[0], 0, 1 );
199 }
200
20123µs1969µs $tmpls = Foswiki::Func::loadTemplate('subscribe') unless defined $tmpls;
# spent 969µs making 1 call to Foswiki::Func::loadTemplate
20222µs $def = "sp$t:$def";
203
20427µs2130µs my $text = Foswiki::Func::expandTemplate($def);
# spent 130µs making 2 calls to Foswiki::Func::expandTemplate, avg 65µs/call
205
206 # Instantiate parameters for maketexts
20721µs my $c = 1;
20822µs foreach my $p (@_) {
209210µs $text =~ s/%PARAM$c%/$p/g;
21022µs $c++;
211 }
21229µs21.21ms return Foswiki::Func::expandCommonVariables($text);
# spent 1.21ms making 2 calls to Foswiki::Func::expandCommonVariables, avg 603µs/call
213}
214
215# Handle a (un)subscription request
216sub _subscribe {
217 my ( $web, $topics, $subscriber, $cur_user, $unsubscribe ) = @_;
218 my $mess = '';
219
220 return ( _template_text( 'bad_subscriber', $subscriber ), 400 )
221 if !(
222 (
223 $Foswiki::cfg{LoginNameFilterIn}
224 && $subscriber =~ m/($Foswiki::cfg{LoginNameFilterIn})/
225 )
226 || $subscriber =~ m/^([A-Z0-9._%-]+@[A-Z0-9.-]+\.[A-Z]{2,4})$/i
227 || $subscriber =~ m/($Foswiki::regex{wikiWordRegex})/
228 )
229 || $subscriber eq $Foswiki::cfg{DefaultUserWikiName};
230 $subscriber = $1; # untaint
231
232 if ( Foswiki::Func::isTrue($unsubscribe) ) {
233 $unsubscribe = '-';
234 }
235 else {
236 undef $unsubscribe;
237 }
238 require Foswiki::Contrib::MailerContrib;
239 my $status = 200;
240 try {
241 Foswiki::Contrib::MailerContrib::changeSubscription( $web, $subscriber,
242 $topics, $unsubscribe );
243 $mess = _template_text( ( $unsubscribe ? 'un' : '' ) . 'subscribe_done',
244 $subscriber, $web, $topics );
245 }
246 catch Error with {
247 $mess = _template_text( 'cannot_change', shift->{-text} );
248 $status = 400;
249 };
250 return ( $mess, $status );
251}
252
25314µs1;
254__END__