Filename | /var/www/foswikidev/core/lib/Foswiki/Plugins/SubscribePlugin.pm |
Statements | Executed 100 statements in 1.64ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
2 | 1 | 1 | 3.35ms | 91.9ms | _SUBSCRIBE | Foswiki::Plugins::SubscribePlugin::
2 | 1 | 1 | 52µs | 2.36ms | _template_text | Foswiki::Plugins::SubscribePlugin::
2 | 1 | 1 | 39µs | 532µs | _getNonce | Foswiki::Plugins::SubscribePlugin::
1 | 1 | 1 | 35µs | 109µs | initPlugin | Foswiki::Plugins::SubscribePlugin::
1 | 1 | 1 | 14µs | 27µs | BEGIN@14 | Foswiki::Plugins::SubscribePlugin::
1 | 1 | 1 | 12µs | 130µs | BEGIN@18 | Foswiki::Plugins::SubscribePlugin::
1 | 1 | 1 | 10µs | 36µs | BEGIN@17 | Foswiki::Plugins::SubscribePlugin::
1 | 1 | 1 | 4µs | 4µs | BEGIN@19 | Foswiki::Plugins::SubscribePlugin::
1 | 1 | 1 | 4µs | 4µs | BEGIN@16 | Foswiki::Plugins::SubscribePlugin::
1 | 1 | 1 | 4µs | 4µs | BEGIN@15 | Foswiki::Plugins::SubscribePlugin::
0 | 0 | 0 | 0s | 0s | __ANON__[:245] | Foswiki::Plugins::SubscribePlugin::
0 | 0 | 0 | 0s | 0s | __ANON__[:249] | Foswiki::Plugins::SubscribePlugin::
0 | 0 | 0 | 0s | 0s | _rest_subscribe | Foswiki::Plugins::SubscribePlugin::
0 | 0 | 0 | 0s | 0s | _subscribe | Foswiki::Plugins::SubscribePlugin::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | # See the bottom of the file for description, copyright and license information | ||||
2 | package Foswiki::Plugins::SubscribePlugin; | ||||
3 | |||||
4 | =begin TML | ||||
5 | |||||
6 | This plugin supports a subscription button that, when embedded in a topic, | ||||
7 | will add the clicker to the WebNotify for that topic. It uses the API | ||||
8 | published by the MailerContrib to manage the subscriptions in WebNotify. | ||||
9 | |||||
10 | WikiGuest cannot be subscribed, only logged-in users. | ||||
11 | |||||
12 | =cut | ||||
13 | |||||
14 | 2 | 27µs | 2 | 41µ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 # spent 27µs making 1 call to Foswiki::Plugins::SubscribePlugin::BEGIN@14
# spent 14µs making 1 call to strict::import |
15 | 2 | 20µs | 1 | 4µ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 # spent 4µs making 1 call to Foswiki::Plugins::SubscribePlugin::BEGIN@15 |
16 | 2 | 23µs | 1 | 4µ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 # spent 4µs making 1 call to Foswiki::Plugins::SubscribePlugin::BEGIN@16 |
17 | 2 | 28µs | 2 | 63µ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 # spent 36µs making 1 call to Foswiki::Plugins::SubscribePlugin::BEGIN@17
# spent 26µs making 1 call to Exporter::import |
18 | 2 | 30µs | 2 | 248µ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 # spent 130µs making 1 call to Foswiki::Plugins::SubscribePlugin::BEGIN@18
# spent 118µs making 1 call to Error::import |
19 | 2 | 1.20ms | 1 | 4µ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 # spent 4µs making 1 call to Foswiki::Plugins::SubscribePlugin::BEGIN@19 |
20 | |||||
21 | 1 | 600ns | our $VERSION = '3.4'; | ||
22 | 1 | 200ns | our $RELEASE = '27 Jul 2015'; | ||
23 | 1 | 400ns | our $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.'; | ||||
25 | 1 | 200ns | our $NO_PREFS_IN_TOPIC = 1; | ||
26 | |||||
27 | 1 | 100ns | our $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 | ||||
30 | 1 | 1µs | my ( $TOPIC, $WEB ) = @_; | ||
31 | |||||
32 | 1 | 2µs | 1 | 1µ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. | ||||
35 | 1 | 3µs | 1 | 23µ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 | |||||
38 | 1 | 700ns | 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) | ||||
49 | 1 | 2µs | 1 | 1µs | Foswiki::Func::getContext()->{'SubscribePluginAllowed'} = 0 # spent 1µs making 1 call to Foswiki::Func::getContext |
50 | if ( Foswiki::Func::getContext()->{'static'} ); | ||||
51 | |||||
52 | 1 | 2µs | 1 | 16µs | Foswiki::Func::registerTagHandler( 'SUBSCRIBE', \&_SUBSCRIBE ); # spent 16µs making 1 call to Foswiki::Func::registerTagHandler |
53 | 1 | 3µs | 1 | 21µ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 | |||||
60 | 1 | 2µs | 1 | 12µs | Foswiki::Plugins::JQueryPlugin::registerPlugin( 'Subscribe', # spent 12µs making 1 call to Foswiki::Plugins::JQueryPlugin::registerPlugin |
61 | 'Foswiki::Plugins::SubscribePlugin::JQuery' ); | ||||
62 | |||||
63 | 1 | 1µs | undef $tmpls; | ||
64 | 1 | 4µ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 | ||||
69 | 2 | 3µs | my ( $session, $params, $topic, $web ) = @_; | ||
70 | |||||
71 | 2 | 4µs | 2 | 3µs | return '' # spent 3µs making 2 calls to Foswiki::Func::getContext, avg 1µs/call |
72 | unless ( Foswiki::Func::getContext()->{'SubscribePluginAllowed'} ); | ||||
73 | |||||
74 | 2 | 5µs | 2 | 41µs | my $cur_user = Foswiki::Func::getWikiName(); # spent 41µs making 2 calls to Foswiki::Func::getWikiName, avg 20µs/call |
75 | 2 | 2µs | my $who = $params->{who} || $cur_user; | ||
76 | 2 | 2µs | my $render = $params->{render} || 'text'; # Rendering icon or text link | ||
77 | |||||
78 | # Guest user cannot subscribe | ||||
79 | 2 | 2µs | return '' if ( $who eq $Foswiki::cfg{DefaultUserWikiName} ); | ||
80 | |||||
81 | 2 | 700ns | if ( defined $params->{topic} ) { | ||
82 | ( $web, $topic ) = | ||||
83 | Foswiki::Func::normalizeWebTopicName( $web, $params->{topic} ); | ||||
84 | } | ||||
85 | 2 | 87µs | require Foswiki::Contrib::MailerContrib; | ||
86 | 2 | 10µs | 2 | 74.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; | ||||
90 | 2 | 4µs | 2 | 19µs | my $doUnsubscribe = Foswiki::isTrue($unsubscribe); # spent 19µs making 2 calls to Foswiki::isTrue, avg 10µs/call |
91 | |||||
92 | 2 | 10µs | 2 | 2.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 | |||||
95 | 2 | 7µs | 4 | 11µ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 | |||||
98 | 2 | 5µs | $tmpl =~ s/\$action/$action/g; | ||
99 | 2 | 12µs | $tmpl =~ s/\$topic/$web.$topic/g; | ||
100 | 2 | 11µs | $tmpl =~ s/\$(subscriber|wikiname)/$who/g; | ||
101 | 2 | 7µs | $tmpl =~ s/\$remove/$unsubscribe/g; | ||
102 | 2 | 15µs | 2 | 532µs | $tmpl =~ s/\$nonce/_getNonce($session)/ge; # spent 532µs making 2 calls to Foswiki::Plugins::SubscribePlugin::_getNonce, avg 266µs/call |
103 | |||||
104 | 2 | 9µs | 2 | 2.09ms | Foswiki::Plugins::JQueryPlugin::createPlugin("subscribe"); # spent 2.09ms making 2 calls to Foswiki::Plugins::JQueryPlugin::createPlugin, avg 1.05ms/call |
105 | |||||
106 | 2 | 8µ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) | ||||
112 | sub _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 | ||||
176 | 2 | 2µs | my ($session) = @_; | ||
177 | 2 | 3µs | require Foswiki::Validation; | ||
178 | 2 | 4µs | 2 | 14µs | my $query = Foswiki::Func::getCgiQuery(); # spent 14µs making 2 calls to Foswiki::Func::getCgiQuery, avg 7µs/call |
179 | 2 | 14µs | 2 | 442µ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 |
180 | 2 | 6µs | 2 | 37µs | my $cgis = $session->getCGISession(); # spent 37µs making 2 calls to Foswiki::getCGISession, avg 18µs/call |
181 | 2 | 7µ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 | ||||
194 | 2 | 900ns | my $def = shift; | ||
195 | 2 | 1µs | my $t = ''; | ||
196 | |||||
197 | 2 | 7µs | if ( $_[0] && $_[0] =~ m/^(text|icon)$/ ) { | ||
198 | $t = substr( $_[0], 0, 1 ); | ||||
199 | } | ||||
200 | |||||
201 | 2 | 3µs | 1 | 969µs | $tmpls = Foswiki::Func::loadTemplate('subscribe') unless defined $tmpls; # spent 969µs making 1 call to Foswiki::Func::loadTemplate |
202 | 2 | 2µs | $def = "sp$t:$def"; | ||
203 | |||||
204 | 2 | 7µs | 2 | 130µ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 | ||||
207 | 2 | 1µs | my $c = 1; | ||
208 | 2 | 2µs | foreach my $p (@_) { | ||
209 | 2 | 10µs | $text =~ s/%PARAM$c%/$p/g; | ||
210 | 2 | 2µs | $c++; | ||
211 | } | ||||
212 | 2 | 9µs | 2 | 1.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 | ||||
216 | sub _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 | |||||
253 | 1 | 4µs | 1; | ||
254 | __END__ |