Filename | /var/www/foswikidev/core/lib/Foswiki/Plugins/NatEditPlugin.pm |
Statements | Executed 36 statements in 1.21ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
1 | 1 | 1 | 38µs | 100µs | initPlugin | Foswiki::Plugins::NatEditPlugin::
1 | 1 | 1 | 14µs | 27µs | BEGIN@15 | Foswiki::Plugins::NatEditPlugin::
1 | 1 | 1 | 13µs | 22µs | BEGIN@27 | Foswiki::Plugins::NatEditPlugin::
1 | 1 | 1 | 11µs | 20µs | BEGIN@24 | Foswiki::Plugins::NatEditPlugin::
1 | 1 | 1 | 10µs | 14µs | BEGIN@16 | Foswiki::Plugins::NatEditPlugin::
1 | 1 | 1 | 9µs | 39µs | BEGIN@41 | Foswiki::Plugins::NatEditPlugin::
1 | 1 | 1 | 8µs | 19µs | BEGIN@29 | Foswiki::Plugins::NatEditPlugin::
1 | 1 | 1 | 4µs | 4µs | BEGIN@18 | Foswiki::Plugins::NatEditPlugin::
1 | 1 | 1 | 3µs | 3µs | BEGIN@20 | Foswiki::Plugins::NatEditPlugin::
1 | 1 | 1 | 3µs | 3µs | BEGIN@21 | Foswiki::Plugins::NatEditPlugin::
1 | 1 | 1 | 3µs | 3µs | BEGIN@19 | Foswiki::Plugins::NatEditPlugin::
1 | 1 | 1 | 3µs | 3µs | BEGIN@22 | Foswiki::Plugins::NatEditPlugin::
0 | 0 | 0 | 0s | 0s | __ANON__[:60] | Foswiki::Plugins::NatEditPlugin::
0 | 0 | 0 | 0s | 0s | __ANON__[:67] | Foswiki::Plugins::NatEditPlugin::
0 | 0 | 0 | 0s | 0s | __ANON__[:77] | Foswiki::Plugins::NatEditPlugin::
0 | 0 | 0 | 0s | 0s | __ANON__[:89] | Foswiki::Plugins::NatEditPlugin::
0 | 0 | 0 | 0s | 0s | beforeEditHandler | Foswiki::Plugins::NatEditPlugin::
0 | 0 | 0 | 0s | 0s | beforeSaveHandler | Foswiki::Plugins::NatEditPlugin::
0 | 0 | 0 | 0s | 0s | writeDebug | Foswiki::Plugins::NatEditPlugin::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | # Copyright (C) 2007-2015 Michael Daum http://michaeldaumconsulting.com | ||||
2 | # | ||||
3 | # This program is free software; you can redistribute it and/or | ||||
4 | # modify it under the terms of the GNU General Public License | ||||
5 | # as published by the Free Software Foundation; either version 2 | ||||
6 | # of the License, or (at your option) any later version. For | ||||
7 | # more details read LICENSE in the root of this distribution. | ||||
8 | # | ||||
9 | # This program is distributed in the hope that it will be useful, | ||||
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||||
12 | |||||
13 | package Foswiki::Plugins::NatEditPlugin; | ||||
14 | |||||
15 | 2 | 33µs | 2 | 41µs | # spent 27µs (14+13) within Foswiki::Plugins::NatEditPlugin::BEGIN@15 which was called:
# once (14µs+13µs) by Foswiki::Plugin::BEGIN@2.27 at line 15 # spent 27µs making 1 call to Foswiki::Plugins::NatEditPlugin::BEGIN@15
# spent 13µs making 1 call to strict::import |
16 | 2 | 25µs | 2 | 18µs | # spent 14µs (10+4) within Foswiki::Plugins::NatEditPlugin::BEGIN@16 which was called:
# once (10µs+4µs) by Foswiki::Plugin::BEGIN@2.27 at line 16 # spent 14µs making 1 call to Foswiki::Plugins::NatEditPlugin::BEGIN@16
# spent 4µs making 1 call to warnings::import |
17 | |||||
18 | 2 | 19µs | 1 | 4µs | # spent 4µs within Foswiki::Plugins::NatEditPlugin::BEGIN@18 which was called:
# once (4µs+0s) by Foswiki::Plugin::BEGIN@2.27 at line 18 # spent 4µs making 1 call to Foswiki::Plugins::NatEditPlugin::BEGIN@18 |
19 | 2 | 18µs | 1 | 3µs | # spent 3µs within Foswiki::Plugins::NatEditPlugin::BEGIN@19 which was called:
# once (3µs+0s) by Foswiki::Plugin::BEGIN@2.27 at line 19 # spent 3µs making 1 call to Foswiki::Plugins::NatEditPlugin::BEGIN@19 |
20 | 2 | 18µs | 1 | 3µs | # spent 3µs within Foswiki::Plugins::NatEditPlugin::BEGIN@20 which was called:
# once (3µs+0s) by Foswiki::Plugin::BEGIN@2.27 at line 20 # spent 3µs making 1 call to Foswiki::Plugins::NatEditPlugin::BEGIN@20 |
21 | 2 | 18µs | 1 | 3µs | # spent 3µs within Foswiki::Plugins::NatEditPlugin::BEGIN@21 which was called:
# once (3µs+0s) by Foswiki::Plugin::BEGIN@2.27 at line 21 # spent 3µs making 1 call to Foswiki::Plugins::NatEditPlugin::BEGIN@21 |
22 | 2 | 42µs | 1 | 3µs | # spent 3µs within Foswiki::Plugins::NatEditPlugin::BEGIN@22 which was called:
# once (3µs+0s) by Foswiki::Plugin::BEGIN@2.27 at line 22 # spent 3µs making 1 call to Foswiki::Plugins::NatEditPlugin::BEGIN@22 |
23 | |||||
24 | # spent 20µs (11+9) within Foswiki::Plugins::NatEditPlugin::BEGIN@24 which was called:
# once (11µs+9µs) by Foswiki::Plugin::BEGIN@2.27 at line 31 | ||||
25 | # Backwards compatibility for Foswiki 1.1.x | ||||
26 | 1 | 6µs | 1 | 9µs | unless ( Foswiki::Request->can('multi_param') ) { # spent 9µs making 1 call to CGI::can |
27 | 2 | 37µs | 2 | 32µs | # spent 22µs (13+9) within Foswiki::Plugins::NatEditPlugin::BEGIN@27 which was called:
# once (13µs+9µs) by Foswiki::Plugin::BEGIN@2.27 at line 27 # spent 22µs making 1 call to Foswiki::Plugins::NatEditPlugin::BEGIN@27
# spent 10µs making 1 call to warnings::unimport |
28 | *Foswiki::Request::multi_param = \&Foswiki::Request::param; | ||||
29 | 2 | 25µs | 2 | 31µs | # spent 19µs (8+11) within Foswiki::Plugins::NatEditPlugin::BEGIN@29 which was called:
# once (8µs+11µs) by Foswiki::Plugin::BEGIN@2.27 at line 29 # spent 19µs making 1 call to Foswiki::Plugins::NatEditPlugin::BEGIN@29
# spent 11µs making 1 call to warnings::import |
30 | } | ||||
31 | 1 | 74µs | 1 | 20µs | } # spent 20µs making 1 call to Foswiki::Plugins::NatEditPlugin::BEGIN@24 |
32 | |||||
33 | 1 | 600ns | our $VERSION = '9.04'; | ||
34 | 1 | 200ns | our $RELEASE = '30 Jul 2015'; | ||
35 | 1 | 200ns | our $NO_PREFS_IN_TOPIC = 1; | ||
36 | 1 | 200ns | our $SHORTDESCRIPTION = 'A Wikiwyg Editor'; | ||
37 | 1 | 100ns | our $baseWeb; | ||
38 | 1 | 100ns | our $baseTopic; | ||
39 | 1 | 100ns | our $doneNonce; | ||
40 | |||||
41 | 2 | 862µs | 2 | 69µs | # spent 39µs (9+30) within Foswiki::Plugins::NatEditPlugin::BEGIN@41 which was called:
# once (9µs+30µs) by Foswiki::Plugin::BEGIN@2.27 at line 41 # spent 39µs making 1 call to Foswiki::Plugins::NatEditPlugin::BEGIN@41
# spent 30µs making 1 call to constant::import |
42 | |||||
43 | ############################################################################### | ||||
44 | sub writeDebug { | ||||
45 | return unless TRACE; | ||||
46 | print STDERR "- NatEditPlugin - " . $_[0] . "\n"; | ||||
47 | |||||
48 | #Foswiki::Func::writeDebug("- NatEditPlugin - $_[0]"); | ||||
49 | } | ||||
50 | |||||
51 | ############################################################################### | ||||
52 | # spent 100µs (38+62) within Foswiki::Plugins::NatEditPlugin::initPlugin which was called:
# once (38µs+62µ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 | ||||
53 | 1 | 2µs | ( $baseTopic, $baseWeb ) = @_; | ||
54 | |||||
55 | Foswiki::Func::registerTagHandler( | ||||
56 | 'NATFORMBUTTON', | ||||
57 | sub { | ||||
58 | require Foswiki::Plugins::NatEditPlugin::FormButton; | ||||
59 | return Foswiki::Plugins::NatEditPlugin::FormButton::handle(@_); | ||||
60 | } | ||||
61 | 1 | 4µs | 1 | 15µs | ); # spent 15µs making 1 call to Foswiki::Func::registerTagHandler |
62 | Foswiki::Func::registerTagHandler( | ||||
63 | 'NATFORMLIST', | ||||
64 | sub { | ||||
65 | require Foswiki::Plugins::NatEditPlugin::FormList; | ||||
66 | return Foswiki::Plugins::NatEditPlugin::FormList::handle(@_); | ||||
67 | } | ||||
68 | 1 | 5µs | 1 | 11µs | ); # spent 11µs making 1 call to Foswiki::Func::registerTagHandler |
69 | |||||
70 | # SMELL: wrapper around normal save not being able to handle | ||||
71 | # utf8->sitecharset conversion. | ||||
72 | Foswiki::Func::registerRESTHandler( | ||||
73 | 'save', | ||||
74 | sub { | ||||
75 | require Foswiki::Plugins::NatEditPlugin::RestSave; | ||||
76 | return Foswiki::Plugins::NatEditPlugin::RestSave::handle(@_); | ||||
77 | }, | ||||
78 | 1 | 5µs | 1 | 20µs | authenticate => 1, # save always requires authentication # spent 20µs making 1 call to Foswiki::Func::registerRESTHandler |
79 | validate => 1, # and validation | ||||
80 | http_allow => 'POST', # updates: restrict to POST. | ||||
81 | description => 'Save or preview results of an edit.' | ||||
82 | ); | ||||
83 | |||||
84 | Foswiki::Func::registerRESTHandler( | ||||
85 | "attachments", | ||||
86 | sub { | ||||
87 | require Foswiki::Plugins::NatEditPlugin::RestAttachments; | ||||
88 | return Foswiki::Plugins::NatEditPlugin::RestAttachments::handle(@_); | ||||
89 | }, | ||||
90 | 1 | 5µs | 1 | 15µs | authenticate => 0, # handler checks it's own security. # spent 15µs making 1 call to Foswiki::Func::registerRESTHandler |
91 | validate => 0, # doesn't update. | ||||
92 | http_allow => 'GET,POST', # doesn't update. | ||||
93 | description => 'Expand the list of attachments.' | ||||
94 | ); | ||||
95 | |||||
96 | 1 | 600ns | $doneNonce = 0; | ||
97 | |||||
98 | 1 | 6µs | return 1; | ||
99 | } | ||||
100 | |||||
101 | ############################################################################### | ||||
102 | # This function will store the TopicTitle in a preference variable if it isn't | ||||
103 | # part of the DataForm of this topic. In a way, we do the reverse of | ||||
104 | # WebDB::onReload() where the TopicTitle is extracted and put into the cache. | ||||
105 | sub beforeSaveHandler { | ||||
106 | my ( $text, $topic, $web, $meta ) = @_; | ||||
107 | |||||
108 | writeDebug("called beforeSaveHandler($web, $topic)"); | ||||
109 | |||||
110 | # find out if we received a TopicTitle | ||||
111 | my $request = Foswiki::Func::getCgiQuery(); | ||||
112 | |||||
113 | my $newTopic = $request->param('newtopic'); | ||||
114 | $newTopic = Foswiki::Sandbox::untaint( $newTopic, | ||||
115 | \&Foswiki::Sandbox::validateTopicName ); | ||||
116 | |||||
117 | my $topicTitle = $request->param('TopicTitle'); | ||||
118 | $topicTitle = Foswiki::Sandbox::untaintUnchecked($topicTitle); | ||||
119 | |||||
120 | # the "newtopic" urlparam either holds a new topic name in case of a rename action, | ||||
121 | # or a boolean flag indicating that the topic being created is a new topic | ||||
122 | if ( defined($newTopic) | ||||
123 | && $newTopic ne '' | ||||
124 | && $newTopic ne '1' | ||||
125 | && $newTopic ne $topic ) | ||||
126 | { | ||||
127 | writeDebug("not saving the topic being rename ... no action"); | ||||
128 | return; | ||||
129 | } | ||||
130 | |||||
131 | unless ( defined $topicTitle ) { | ||||
132 | writeDebug("didn't get a TopicTitle, nothing do here"); | ||||
133 | return; | ||||
134 | } | ||||
135 | |||||
136 | if ( $topicTitle =~ m/X{10}|AUTOINC\d/ ) { | ||||
137 | writeDebug("ignoring topic being auto-generated"); | ||||
138 | return; | ||||
139 | } | ||||
140 | |||||
141 | my $fieldTopicTitle = $meta->get( 'FIELD', 'TopicTitle' ); | ||||
142 | writeDebug("topic=$web.$topic, topicTitle=$topicTitle"); | ||||
143 | |||||
144 | if ( $topicTitle eq $topic ) { | ||||
145 | writeDebug("same as topic name ... nulling"); | ||||
146 | $request->param( "TopicTitle", "" ); | ||||
147 | $topicTitle = ''; | ||||
148 | if ( defined $fieldTopicTitle ) { | ||||
149 | $fieldTopicTitle->{value} = ""; | ||||
150 | } | ||||
151 | } | ||||
152 | |||||
153 | # find out if this topic can store the TopicTitle in its metadata | ||||
154 | if ( defined $fieldTopicTitle ) { | ||||
155 | writeDebug("storing it into the formfield"); | ||||
156 | |||||
157 | # however, check if we've got a TOPICTITLE preference setting | ||||
158 | # if so remove it. this happens if we stored a topic title but | ||||
159 | # then added a form that now takes the topic title instead | ||||
160 | if ( defined $meta->get( 'PREFERENCE', 'TOPICTITLE' ) ) { | ||||
161 | writeDebug("removing redundant TopicTitles in preferences"); | ||||
162 | $meta->remove( 'PREFERENCE', 'TOPICTITLE' ); | ||||
163 | } | ||||
164 | |||||
165 | $fieldTopicTitle->{value} = $topicTitle; | ||||
166 | return; | ||||
167 | } | ||||
168 | |||||
169 | writeDebug("we need to store the TopicTitle in the preferences"); | ||||
170 | |||||
171 | # if it is a topic setting, override it. | ||||
172 | my $topicTitleHash = $meta->get( 'PREFERENCE', 'TOPICTITLE' ); | ||||
173 | if ( defined $topicTitleHash ) { | ||||
174 | writeDebug( | ||||
175 | "found old TopicTitle in preference settings: $topicTitleHash->{value}" | ||||
176 | ); | ||||
177 | if ($topicTitle) { | ||||
178 | |||||
179 | # set the new value | ||||
180 | $topicTitleHash->{value} = $topicTitle; | ||||
181 | } | ||||
182 | else { | ||||
183 | |||||
184 | # remove the value if the new TopicTitle is an empty string | ||||
185 | $meta->remove( 'PREFERENCE', 'TOPICTITLE' ); | ||||
186 | } | ||||
187 | return; | ||||
188 | } | ||||
189 | |||||
190 | writeDebug("no TopicTitle in preference settings"); | ||||
191 | |||||
192 | # if it is a bullet setting, replace it. | ||||
193 | if ( $text =~ | ||||
194 | s/((?:^|[\n\r])(?:\t| )+\*\s+(?:Set|Local)\s+TOPICTITLE\s*=\s*)(.*)((?:$|[\r\n]))/$1$topicTitle$3/ | ||||
195 | ) | ||||
196 | { | ||||
197 | writeDebug("found old TopicTitle defined as a bullet setting: $2"); | ||||
198 | $_[0] = $text; | ||||
199 | return; | ||||
200 | } | ||||
201 | |||||
202 | writeDebug( | ||||
203 | "no TopicTitle stored anywhere. creating a new preference setting"); | ||||
204 | |||||
205 | if ($topicTitle) { # but only if we don't set it to the empty string | ||||
206 | $meta->putKeyed( | ||||
207 | 'PREFERENCE', | ||||
208 | { | ||||
209 | name => 'TOPICTITLE', | ||||
210 | title => 'TOPICTITLE', | ||||
211 | type => 'Local', | ||||
212 | value => $topicTitle | ||||
213 | } | ||||
214 | ); | ||||
215 | } | ||||
216 | } | ||||
217 | |||||
218 | ############################################################################### | ||||
219 | # make sure there's a new nonce for consecutive save+continues | ||||
220 | sub beforeEditHandler { | ||||
221 | my ( $text, $topic, $web, $error, $meta ) = @_; | ||||
222 | |||||
223 | return if $doneNonce; | ||||
224 | $doneNonce = 1; | ||||
225 | |||||
226 | my $session = $Foswiki::Plugins::SESSION; | ||||
227 | my $cgis = $session->getCGISession(); | ||||
228 | return unless $cgis; | ||||
229 | |||||
230 | my $response = $session->{response}; | ||||
231 | my $request = $session->{request}; | ||||
232 | |||||
233 | my $context = $request->url( -full => 1, -path => 1, -query => 1 ) . time(); | ||||
234 | my $useStrikeOne = ( $Foswiki::cfg{Validation}{Method} eq 'strikeone' ); | ||||
235 | my $nonce; | ||||
236 | |||||
237 | if ( Foswiki::Validation->can('generateValidationKey') ) { | ||||
238 | |||||
239 | # newer foswikis have a proper api for things like this | ||||
240 | $nonce = Foswiki::Validation::generateValidationKey( $cgis, $context, | ||||
241 | $useStrikeOne ); | ||||
242 | } | ||||
243 | else { | ||||
244 | |||||
245 | # older ones get a quick and dirty approach | ||||
246 | my $result = Foswiki::Validation::addValidationKey( $cgis, $context, | ||||
247 | $useStrikeOne ); | ||||
248 | if ( $result =~ m/value='(.*)'/ ) { | ||||
249 | $nonce = $1; | ||||
250 | } | ||||
251 | } | ||||
252 | |||||
253 | #print STDERR "nonce=$nonce\n"; | ||||
254 | |||||
255 | $response->pushHeader( 'X-Foswiki-Validation', $nonce ) if defined $nonce; | ||||
256 | } | ||||
257 | |||||
258 | 1 | 4µs | 1; |