← 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/ActionTrackerPlugin.pm
StatementsExecuted 54 statements in 3.08ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
111678µs757µsFoswiki::Plugins::ActionTrackerPlugin::::BEGIN@33Foswiki::Plugins::ActionTrackerPlugin::BEGIN@33
1311214µs214µsFoswiki::Plugins::ActionTrackerPlugin::::commonTagsHandlerFoswiki::Plugins::ActionTrackerPlugin::commonTagsHandler
11153µs3.21msFoswiki::Plugins::ActionTrackerPlugin::::initPluginFoswiki::Plugins::ActionTrackerPlugin::initPlugin
11114µs27µsFoswiki::Plugins::ActionTrackerPlugin::::BEGIN@4Foswiki::Plugins::ActionTrackerPlugin::BEGIN@4
11114µs217µsFoswiki::Plugins::ActionTrackerPlugin::::BEGIN@6Foswiki::Plugins::ActionTrackerPlugin::BEGIN@6
11110µs24µsFoswiki::Plugins::ActionTrackerPlugin::::BEGIN@5Foswiki::Plugins::ActionTrackerPlugin::BEGIN@5
1114µs4µsFoswiki::Plugins::ActionTrackerPlugin::::BEGIN@8Foswiki::Plugins::ActionTrackerPlugin::BEGIN@8
1113µs3µsFoswiki::Plugins::ActionTrackerPlugin::::BEGIN@9Foswiki::Plugins::ActionTrackerPlugin::BEGIN@9
0000s0sFoswiki::Plugins::ActionTrackerPlugin::::__ANON__[:558]Foswiki::Plugins::ActionTrackerPlugin::__ANON__[:558]
0000s0sFoswiki::Plugins::ActionTrackerPlugin::::__ANON__[:563]Foswiki::Plugins::ActionTrackerPlugin::__ANON__[:563]
0000s0sFoswiki::Plugins::ActionTrackerPlugin::::__ANON__[:568]Foswiki::Plugins::ActionTrackerPlugin::__ANON__[:568]
0000s0sFoswiki::Plugins::ActionTrackerPlugin::::_addMissingAttributesFoswiki::Plugins::ActionTrackerPlugin::_addMissingAttributes
0000s0sFoswiki::Plugins::ActionTrackerPlugin::::_beforeActionEditFoswiki::Plugins::ActionTrackerPlugin::_beforeActionEdit
0000s0sFoswiki::Plugins::ActionTrackerPlugin::::_beforeNormalEditFoswiki::Plugins::ActionTrackerPlugin::_beforeNormalEdit
0000s0sFoswiki::Plugins::ActionTrackerPlugin::::_handleActionNotifyFoswiki::Plugins::ActionTrackerPlugin::_handleActionNotify
0000s0sFoswiki::Plugins::ActionTrackerPlugin::::_handleActionSearchFoswiki::Plugins::ActionTrackerPlugin::_handleActionSearch
0000s0sFoswiki::Plugins::ActionTrackerPlugin::::_hiddenMetaFoswiki::Plugins::ActionTrackerPlugin::_hiddenMeta
0000s0sFoswiki::Plugins::ActionTrackerPlugin::::_updateRESTHandlerFoswiki::Plugins::ActionTrackerPlugin::_updateRESTHandler
0000s0sFoswiki::Plugins::ActionTrackerPlugin::::_updateSingleActionFoswiki::Plugins::ActionTrackerPlugin::_updateSingleAction
0000s0sFoswiki::Plugins::ActionTrackerPlugin::::afterEditHandlerFoswiki::Plugins::ActionTrackerPlugin::afterEditHandler
0000s0sFoswiki::Plugins::ActionTrackerPlugin::::beforeEditHandlerFoswiki::Plugins::ActionTrackerPlugin::beforeEditHandler
0000s0sFoswiki::Plugins::ActionTrackerPlugin::::beforeSaveHandlerFoswiki::Plugins::ActionTrackerPlugin::beforeSaveHandler
0000s0sFoswiki::Plugins::ActionTrackerPlugin::::lazyInitFoswiki::Plugins::ActionTrackerPlugin::lazyInit
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
2package Foswiki::Plugins::ActionTrackerPlugin;
3
4227µs240µs
# spent 27µs (14+13) within Foswiki::Plugins::ActionTrackerPlugin::BEGIN@4 which was called: # once (14µs+13µs) by Foswiki::Plugin::BEGIN@2.3 at line 4
use strict;
# spent 27µs making 1 call to Foswiki::Plugins::ActionTrackerPlugin::BEGIN@4 # spent 13µs making 1 call to strict::import
5233µs238µs
# spent 24µs (10+14) within Foswiki::Plugins::ActionTrackerPlugin::BEGIN@5 which was called: # once (10µs+14µs) by Foswiki::Plugin::BEGIN@2.3 at line 5
use Assert;
# spent 24µs making 1 call to Foswiki::Plugins::ActionTrackerPlugin::BEGIN@5 # spent 14µs making 1 call to Assert::import
6236µs2420µs
# spent 217µs (14+203) within Foswiki::Plugins::ActionTrackerPlugin::BEGIN@6 which was called: # once (14µs+203µs) by Foswiki::Plugin::BEGIN@2.3 at line 6
use Error qw( :try );
# spent 217µs making 1 call to Foswiki::Plugins::ActionTrackerPlugin::BEGIN@6 # spent 203µs making 1 call to Error::import
7
8219µs14µs
# spent 4µs within Foswiki::Plugins::ActionTrackerPlugin::BEGIN@8 which was called: # once (4µs+0s) by Foswiki::Plugin::BEGIN@2.3 at line 8
use Foswiki::Func ();
# spent 4µs making 1 call to Foswiki::Plugins::ActionTrackerPlugin::BEGIN@8
92116µs13µs
# spent 3µs within Foswiki::Plugins::ActionTrackerPlugin::BEGIN@9 which was called: # once (3µs+0s) by Foswiki::Plugin::BEGIN@2.3 at line 9
use Foswiki::Plugins ();
# spent 3µs making 1 call to Foswiki::Plugins::ActionTrackerPlugin::BEGIN@9
10
111700nsour $VERSION = '2.4.10';
121200nsour $RELEASE = '2013-02-27';
131200nsour $SHORTDESCRIPTION =
14'Adds support for action tags in topics, and automatic notification of action statuses';
151200nsour $initialised = 0;
16
171300nsmy $doneHeader = 0;
181100nsmy $actionNumber = 0;
191100nsmy $defaultFormat;
20
21# Map default options
221100nsour $options;
23
24
# spent 3.21ms (53µs+3.16) within Foswiki::Plugins::ActionTrackerPlugin::initPlugin which was called: # once (53µs+3.16ms) by Foswiki::Plugin::__ANON__[/var/www/foswiki11/lib/Foswiki/Plugin.pm:241] at line 234 of /var/www/foswiki11/lib/Foswiki/Plugin.pm
sub initPlugin {
25
261700ns $initialised = 0;
271400ns $doneHeader = 0;
28
2916µs12.80ms Foswiki::Func::registerRESTHandler( 'update', \&_updateRESTHandler );
# spent 2.80ms making 1 call to Foswiki::Func::registerRESTHandler
30
3116µs176µs Foswiki::Func::registerTagHandler( 'ACTIONSEARCH', \&_handleActionSearch,
# spent 76µs making 1 call to Foswiki::Func::registerTagHandler
32 'context-free' );
3322.60ms1757µs
# spent 757µs (678+79) within Foswiki::Plugins::ActionTrackerPlugin::BEGIN@33 which was called: # once (678µs+79µs) by Foswiki::Plugin::BEGIN@2.3 at line 33
use Foswiki::Contrib::JSCalendarContrib;
# spent 757µs making 1 call to Foswiki::Plugins::ActionTrackerPlugin::BEGIN@33
34128µs112µs if ( $@ || !$Foswiki::Contrib::JSCalendarContrib::VERSION ) {
# spent 12µs making 1 call to version::(bool
35 Foswiki::Func::writeWarning( 'JSCalendarContrib not found ' . $@ );
36 }
37 else {
3817µs1265µs Foswiki::Contrib::JSCalendarContrib::addHEAD('foswiki');
# spent 265µs making 1 call to Foswiki::Contrib::JSCalendarContrib::addHEAD
39 }
40
4119µs return 1;
42}
43
44
# spent 214µs within Foswiki::Plugins::ActionTrackerPlugin::commonTagsHandler which was called 13 times, avg 16µs/call: # 13 times (214µs+0s) by Foswiki::Plugin::invoke at line 294 of /var/www/foswiki11/lib/Foswiki/Plugin.pm, avg 16µs/call
sub commonTagsHandler {
451365µs my ( $otext, $topic, $web, $meta ) = @_;
46
4713127µs return unless ( $_[0] =~ m/%ACTION.*{.*}%/o );
48
49 return unless lazyInit( $web, $topic );
50
51 # Format actions in the topic.
52 # Done this way so we get tables built up by
53 # collapsing successive actions.
54 my $as =
55 Foswiki::Plugins::ActionTrackerPlugin::ActionSet::load( $web, $topic,
56 $otext, 1 );
57 my $actionGroup;
58 my $text = '';
59
60 foreach my $entry ( @{ $as->{ACTIONS} } ) {
61 if ( ref($entry) ) {
62 if ( !$actionGroup ) {
63 $actionGroup =
64 new Foswiki::Plugins::ActionTrackerPlugin::ActionSet();
65 }
66 $actionGroup->add($entry);
67 }
68 elsif ( $entry =~ /(\S|\n\s*\n)/s ) {
69 if ($actionGroup) {
70 $text .= $actionGroup->formatAsHTML( $defaultFormat, 'atpDef' );
71 $actionGroup = undef;
72 }
73 $text .= $entry;
74 }
75 }
76 if ($actionGroup) {
77 $text .= $actionGroup->formatAsHTML( $defaultFormat, 'atpDef' );
78 }
79
80 $_[0] = $text;
81
82 # COVERAGE OFF debug only
83 if ( $options->{DEBUG} ) {
84 $_[0] =~
85 s/%ACTIONNOTIFICATIONS{(.*?)}%/_handleActionNotify($web, $1)/geo;
86 }
87
88 # COVERAGE ON
89
90}
91
92# This handler is called by the edit script just before presenting
93# the edit text in the edit box.
94# We use it to populate the actionform.tmpl template, which is then
95# inserted in the edit.action.tmpl as the %UNENCODED_TEXT%.
96# We process the %META fields from the raw text of the topic and
97# insert them as hidden fields in the form, so the topic is
98# fully populated.
99sub beforeEditHandler {
100
101 #my( $text, $topic, $web, $meta ) = @_;
102
103 if ( Foswiki::Func::getSkin() =~ /\baction\b/ ) {
104 return _beforeActionEdit(@_);
105 }
106 else {
107 return _beforeNormalEdit(@_);
108 }
109}
110
111sub _beforeNormalEdit {
112
113 #my( $text, $topic, $web, $meta ) = @_;
114 # Coarse method of testing if modern action syntax is used
115 my $oc = scalar( $_[0] =~ m/%ACTION{.*?}%/g );
116 my $cc = scalar( $_[0] =~ m/%ENDACTION%/g );
117
118 if ( $cc < $oc ) {
119 return unless lazyInit( $_[2], $_[1] );
120
121 my $as =
122 Foswiki::Plugins::ActionTrackerPlugin::ActionSet::load( $_[2], $_[1],
123 $_[0], 1 );
124 $_[0] = $as->stringify();
125 }
126}
127
128# Note: a simple return will effectively ignore the action tracker for
129# purposes of this edit. However the skin template will still be expanded,
130# so for clean error handling, make sure $_[0] is set to something.
131sub _beforeActionEdit {
132 my ( $text, $topic, $web, $meta ) = @_;
133
134 return unless lazyInit( $web, $topic );
135
136 my $query = Foswiki::Func::getCgiQuery();
137
138 my $uid = $query->param('atp_action');
139 unless ( defined $uid ) {
140 $_[0] = "Bad URL parameters; atp_action is not set";
141 return;
142 }
143
144 # actionform.tmpl is a sub-template inserted into the parent template
145 # as %TEXT%. This is done so we can use the standard template mechanism
146 # without screwing up the content of the subtemplate.
147 my $tmpl =
148 Foswiki::Func::readTemplate( 'actionform', Foswiki::Func::getSkin() );
149
150 # Here we want to show the current time in same time format as the user
151 # sees elsewhere in his browser on Foswiki.
152 my $date =
153 Foswiki::Func::formatTime( time(), undef,
154 $Foswiki::cfg{DisplayTimeValues} );
155
156 die unless ($date);
157
158 $tmpl =~ s/%DATE%/$date/g;
159 my $user = Foswiki::Func::getWikiUserName();
160 $tmpl =~ s/%WIKIUSERNAME%/$user/go;
161 $tmpl = Foswiki::Func::expandCommonVariables( $tmpl, $topic, $web );
162 $tmpl = Foswiki::Func::renderText( $tmpl, $web );
163
164 # The 'command' parameter is used to signal to the afterEditHandler and
165 # the beforeSaveHandler that they have to handle the fields of the
166 # edit differently
167 my $fields = CGI::hidden( -name => 'closeactioneditor', -value => 1 );
168 $fields .= CGI::hidden( -name => 'cmd', -value => "" );
169
170 # write in hidden fields
171 if ($meta) {
172 $meta->forEachSelectedValue( qr/FIELD/, undef, \&_hiddenMeta,
173 { text => \$fields } );
174 }
175
176 # Find the action.
177 my $as =
178 Foswiki::Plugins::ActionTrackerPlugin::ActionSet::load( $web, $topic,
179 $text, 1 );
180
181 my ( $action, $pre, $post ) = $as->splitOnAction($uid);
182
183 # Make sure the action currently exists
184 unless ($action) {
185 $_[0] = "Action does not exist - cannot edit";
186 return;
187 }
188
189 # Add revision info to support merging
190 my $info = $meta->getRevisionInfo();
191 $fields .= CGI::hidden(
192 -name => 'originalrev',
193 -value => "$info->{version}_$info->{date}"
194 );
195
196 $tmpl =~ s/%UID%/$uid/go;
197
198 $fields .= CGI::hidden(
199 -name => 'unlock',
200 -value => 'on'
201 );
202
203 # If an origin - the name or URL of the topic the edit started in - is
204 # supplied in the query, then use it to redirect to.
205 $fields .= CGI::hidden(
206 -name => 'redirectto',
207 -value => $query->param('origin')
208 ) if $query->param('origin');
209
210 # Legacy support for old templates
211 $tmpl =~ s/%SUBMITCMDNAME%/Save/g;
212 $tmpl =~ s/%SUBMITCOMMAND%/save/g;
213 $tmpl =~ s/%SUBMITCMDOPT%//g;
214
215 my $fmt = new Foswiki::Plugins::ActionTrackerPlugin::Format(
216 $options->{EDITHEADER},
217 $options->{EDITFORMAT},
218 $options->{EDITORIENT},
219 "", ""
220 );
221 my $editable = $action->formatForEdit($fmt);
222 $tmpl =~ s/%EDITFIELDS%/$editable/o;
223
224 $tmpl =~ s/%EBH%/$options->{EDITBOXHEIGHT}/go;
225 $tmpl =~ s/%EBW%/$options->{EDITBOXWIDTH}/go;
226
227 $text = $action->{text};
228
229 # Process the text so it's nice to edit. This gets undone in Action.pm
230 # when the action is saved.
231 $text =~ s/^\t/ /gos;
232 $text =~ s/<br( \/)?>/\n/gios;
233 $text =~ s/<p( \/)?>/\n\n/gios;
234
235 $tmpl =~ s/%TEXT%/$text/go;
236 $tmpl =~ s/%HIDDENFIELDS%/$fields/go;
237
238 $_[0] = $tmpl;
239}
240
241sub _hiddenMeta {
242 my ( $value, $options ) = @_;
243
244 my $name = $options->{_key};
245 ${ $options->{text} } .= CGI::hidden( -name => $name, -value => $value );
246 return $value;
247}
248
249# This handler is called by the preview script just before
250# presenting the text.
251# The skin name is passed over from the original invocation of
252# edit so if the skin is "action" we know we have been editing
253# an action and have to recombine fields to create the
254# actual text.
255# Metadata is handled by the preview script itself.
256sub afterEditHandler {
257 my ( $text, $topic, $web ) = @_;
258
259 my $query = Foswiki::Func::getCgiQuery();
260 return unless ( $query->param('closeactioneditor') );
261
262 return unless lazyInit( $web, $topic );
263
264 my ( $ancestorRev, $ancestorDate ) = ( 0, 0 );
265 my $origin = $query->param('originalrev');
266 ASSERT( defined($origin) ) if DEBUG;
267
268 if ( $origin =~ /^(\d+)_(\d+)$/ ) {
269 ( $ancestorRev, $ancestorDate ) = ( $1, $2 );
270 }
271
272 # Get the most recently saved rev
273 ( my $meta, $text ) = Foswiki::Func::readTopic( $web, $topic );
274 my $info = $meta->getRevisionInfo();
275 my $mustMerge =
276 ( $ancestorRev ne $info->{version}
277 || $ancestorDate && $info->{date} && $ancestorDate ne $info->{date} );
278
279 my $latest_as =
280 Foswiki::Plugins::ActionTrackerPlugin::ActionSet::load( $web, $topic,
281 $text, 1 );
282
283 my $uid = $query->param("uid");
284 ASSERT( defined($uid) ) if DEBUG;
285
286 my $latest_act =
287 $latest_as->search( new Foswiki::Attrs( 'uid="' . $uid . '"' ) )->first;
288
289 my $new_act =
290 Foswiki::Plugins::ActionTrackerPlugin::Action::createFromQuery( $_[2],
291 $_[1], $latest_act->{ACTION_NUMBER}, $query );
292
293 unless (
294 UNIVERSAL::isa(
295 $latest_act, 'Foswiki::Plugins::ActionTrackerPlugin::Action'
296 )
297 )
298 {
299
300# If the edited action was not found in the latest rev, then force it in (it may
301# have been removed in another parallel edit)
302 $latest_act = $new_act;
303 $latest_as->add($new_act);
304 }
305
306 # See if we can get a common ancestor for merging
307 my $old_act;
308 if ($mustMerge) {
309
310 # If we have to merge, we need the ancestor root of the action to
311 # do a three-way merge.
312 # If the previous revision was generated by a reprev,
313 # then the original is lost and we can't 3-way merge
314 unless ( $info->{reprev}
315 && $info->{version}
316 && $info->{reprev} == $info->{version} )
317 {
318
319 my ( $ances_meta, $ances_text ) =
320 Foswiki::Func::readTopic( $web, $topic, $ancestorRev );
321 my $ances =
322 Foswiki::Plugins::ActionTrackerPlugin::ActionSet::load( $web,
323 $topic, $ances_text, $ancestorRev );
324 $old_act =
325 $ances->search( new Foswiki::Attrs( 'uid="' . $uid . '"' ) )
326 ->first;
327 }
328 }
329
330 $latest_act->updateFromCopy( $new_act, $mustMerge, $info->{version},
331 $ancestorRev, $old_act );
332 $latest_act->populateMissingFields();
333 $text = $latest_as->stringify();
334
335 # take the opportunity to fill in the missing fields in actions
336 _addMissingAttributes( $text, $_[1], $_[2] );
337
338 $_[0] = $text;
339}
340
341# Process the actions and add UIDs and other missing attributes
342sub beforeSaveHandler {
343 my ( $text, $topic, $web ) = @_;
344
345 return unless $text;
346
347 return unless lazyInit( $web, $topic );
348
349 my $query = Foswiki::Func::getCgiQuery();
350 return unless ($query);
351
352 if ( $query->param('closeactioneditor') ) {
353
354# this is a save from the action editor. Text will just be the text of the action - we
355# must recover the rest from the topic on disc.
356
357 # Strip pre and post metadata from the text
358 my $premeta = "";
359 my $postmeta = "";
360 my $inpost = 0;
361 my $text = "";
362 foreach my $line ( split( /\r?\n/, $_[0] ) ) {
363 if ( $line =~ /^%META:[^{]+{[^}]*}%/ ) {
364 if ($inpost) {
365 $postmeta .= "$line\n";
366 }
367 else {
368 $premeta .= "$line\n";
369 }
370 }
371 else {
372 $text .= "$line\n";
373 $inpost = 1;
374 }
375 }
376
377 # compose the text
378 afterEditHandler( $text, $topic, $web );
379
380 # reattach the metadata
381 $text .= "\n" unless $text =~ /\n$/s;
382 $postmeta = "\n$postmeta" if $postmeta;
383 $_[0] = $premeta . $text . $postmeta;
384 }
385 else {
386
387 # take the opportunity to fill in the missing fields in actions
388 _addMissingAttributes( $_[0], $topic, $web );
389 }
390}
391
392# PRIVATE Add missing attributes to all actions that don't have them
393sub _addMissingAttributes {
394
395 #my ( $text, $topic, $web ) = @_;
396 my $text = "";
397 my $descr;
398 my $attrs;
399 my $gathering;
400 my $processAction = 0;
401 my $an = 0;
402 my %seenUID;
403
404 my $as =
405 Foswiki::Plugins::ActionTrackerPlugin::ActionSet::load( $_[2], $_[1],
406 $_[0], 1 );
407
408 foreach my $action ( @{ $as->{ACTIONS} } ) {
409 next unless ref($action);
410 $action->populateMissingFields();
411 if ( $seenUID{ $action->{uid} } ) {
412
413 # This can happen if there has been a careless
414 # cut and paste. In this case, the first instance
415 # of the action gets the old UID. This may banjax
416 # change notification, but it's better than the
417 # alternative!
418 $action->{uid} = $action->getNewUID();
419 }
420 $seenUID{ $action->{uid} } = 1;
421 }
422 $_[0] = $as->stringify();
423}
424
425# =========================
426# Perform filtered search for all actions
427sub _handleActionSearch {
428 my ( $session, $attrs, $topic, $web ) = @_;
429
430 return unless lazyInit( $web, $topic );
431
432 # use default format unless overridden
433 my $fmt;
434 my $fmts = $attrs->remove('format');
435 my $plain = Foswiki::Func::isTrue( $attrs->remove('nohtml') );
436 my $hdrs = $attrs->remove('header');
437 my $foot = $attrs->remove('footer');
438 my $sep = $attrs->remove('separator');
439 my $orient = $attrs->remove('orient');
440 my $sort = $attrs->remove('sort');
441 my $reverse = $attrs->remove('reverse');
442
443 $fmts = $defaultFormat->getFields() unless ( defined($fmts) );
444 $hdrs = $defaultFormat->getHeaders() unless ( defined($hdrs) );
445 $orient = $defaultFormat->getOrientation() unless ( defined($orient) );
446 $fmt =
447 new Foswiki::Plugins::ActionTrackerPlugin::Format( $hdrs, $fmts, $orient,
448 $fmts, '', 1 );
449
450 my $actions =
451 Foswiki::Plugins::ActionTrackerPlugin::ActionSet::allActionsInWebs( $web,
452 $attrs, 0 );
453 $actions->sort( $sort, $reverse );
454 my $result;
455 if ($plain) {
456 $result = $actions->formatAsString($fmt);
457 }
458 else {
459 $result = $actions->formatAsHTML( $fmt, 'atpSearch' );
460 }
461 return $result;
462}
463
464# Lazy initialize of plugin 'cause of performance
465sub lazyInit {
466 my ( $web, $topic ) = @_;
467
468 return 1 if $initialised;
469
470 Foswiki::Plugins::JQueryPlugin::registerPlugin( 'ActionTracker',
471 'Foswiki::Plugins::ActionTrackerPlugin::JQuery' );
472 unless (
473 Foswiki::Plugins::JQueryPlugin::createPlugin(
474 'ActionTracker', $Foswiki::Plugins::SESSION
475 )
476 )
477 {
478 die 'Failed to register JQuery plugin';
479 }
480
481 require Foswiki::Attrs;
482 require Foswiki::Plugins::ActionTrackerPlugin::Options;
483 require Foswiki::Plugins::ActionTrackerPlugin::Action;
484 require Foswiki::Plugins::ActionTrackerPlugin::ActionSet;
485 require Foswiki::Plugins::ActionTrackerPlugin::Format;
486
487 $options = Foswiki::Plugins::ActionTrackerPlugin::Options::load();
488
489 # Add the ATP CSS (conditionally included from $options, which is why
490 # it's not done in the JQuery plugin decl)
491 Foswiki::Func::addToZone( "head", "JQUERYPLUGIN::ActionTracker::CSS",
492 <<"HERE");
493<link rel='stylesheet' href='$Foswiki::Plugins::ActionTrackerPlugin::options->{CSS}' type='text/css' media='all' />
494HERE
495
496 $defaultFormat = new Foswiki::Plugins::ActionTrackerPlugin::Format(
497 $options->{TABLEHEADER},
498 $options->{TABLEFORMAT},
499 $options->{TABLEORIENT},
500 $options->{TEXTFORMAT},
501 $options->{NOTIFYCHANGES}, 0
502 );
503
504 if ( $options->{EXTRAS} ) {
505 my $e = Foswiki::Plugins::ActionTrackerPlugin::Action::extendTypes(
506 $options->{EXTRAS} );
507
508 # COVERAGE OFF safety net
509 if ( defined($e) ) {
510 Foswiki::Func::writeWarning(
511 "- Foswiki::Plugins::ActionTrackerPlugin ERROR $e");
512 }
513
514 # COVERAGE ON
515 }
516
517 $initialised = 1;
518
519 return 1;
520}
521
522# PRIVATE return formatted actions that have changed in all webs
523# Debugging only
524# COVERAGE OFF debug only
525sub _handleActionNotify {
526 my ( $web, $expr ) = @_;
527
528 eval 'require Foswiki::Plugins::ActionTrackerPlugin::ActionNotify';
529 if ($@) {
530 Foswiki::Func::writeWarning("ATP: $@");
531 return;
532 }
533
534 my $text =
535 Foswiki::Plugins::ActionTrackerPlugin::ActionNotify::doNotifications(
536 $web, $expr, 1 );
537
538 $text =~ s/<html>/<\/pre>/gios;
539 $text =~ s/<\/html>/<pre>/gios;
540 $text =~ s/<\/?body>//gios;
541 return "<!-- from an --> <pre>$text</pre> <!-- end from an -->";
542}
543
544# COVERAGE ON
545
546sub _updateRESTHandler {
547 my $session = shift;
548 my $query = Foswiki::Func::getCgiQuery();
549 try {
550 my $topic = $query->param('topic');
551 my $web;
552 ( $web, $topic ) =
553 Foswiki::Func::normalizeWebTopicName( undef, $topic );
554 lazyInit( $web, $topic );
555 _updateSingleAction( $web, $topic, $query->param('uid'),
556 $query->param('field') => $query->param('value') );
557 print CGI::header( 'text/plain', 200 ); # simple message
558 }
559 catch Error::Simple with {
560 my $e = shift;
561 print CGI::header( 'text/plain', 500 );
562 print $e->{-text};
563 }
564 catch Foswiki::AccessControlException with {
565 my $e = shift;
566 print CGI::header( 'text/plain', 500 );
567 print $e->stringify();
568 };
569 return undef;
570}
571
572sub _updateSingleAction {
573 my ( $web, $topic, $uid, %changes ) = @_;
574
575 my ( $meta, $text ) = Foswiki::Func::readTopic( $web, $topic );
576
577 my $descr;
578 my $attrs;
579 my $gathering;
580 my $processAction = 0;
581 my $an = 0;
582 my %seenUID;
583
584 my $as =
585 Foswiki::Plugins::ActionTrackerPlugin::ActionSet::load( $web, $topic,
586 $text, 1 );
587
588 foreach my $action ( @{ $as->{ACTIONS} } ) {
589 if ( ref($action) ) {
590 if ( $action->{uid} == $uid ) {
591 foreach my $key ( keys %changes ) {
592 $action->{$key} = $changes{$key};
593 }
594 }
595 }
596 }
597 Foswiki::Func::saveTopic( $web, $topic, $meta, $as->stringify(),
598 { comment => 'atp save' } );
599}
600
60114µs1;
602__END__