← 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/ExpandTopicContentPlugin.pm
StatementsExecuted 20 statements in 719µs
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
11136µs104µsFoswiki::Plugins::ExpandTopicContentPlugin::::initPluginFoswiki::Plugins::ExpandTopicContentPlugin::initPlugin
11114µs27µsFoswiki::Plugins::ExpandTopicContentPlugin::::BEGIN@49Foswiki::Plugins::ExpandTopicContentPlugin::BEGIN@49
1119µs15µsFoswiki::Plugins::ExpandTopicContentPlugin::::BEGIN@50Foswiki::Plugins::ExpandTopicContentPlugin::BEGIN@50
1113µs3µsFoswiki::Plugins::ExpandTopicContentPlugin::::BEGIN@52Foswiki::Plugins::ExpandTopicContentPlugin::BEGIN@52
1113µs3µsFoswiki::Plugins::ExpandTopicContentPlugin::::BEGIN@53Foswiki::Plugins::ExpandTopicContentPlugin::BEGIN@53
1113µs3µsFoswiki::Plugins::ExpandTopicContentPlugin::::BEGIN@54Foswiki::Plugins::ExpandTopicContentPlugin::BEGIN@54
0000s0sFoswiki::Plugins::ExpandTopicContentPlugin::::_EXPANDTOPICFoswiki::Plugins::ExpandTopicContentPlugin::_EXPANDTOPIC
0000s0sFoswiki::Plugins::ExpandTopicContentPlugin::::_REVISIONATTIMEFoswiki::Plugins::ExpandTopicContentPlugin::_REVISIONATTIME
0000s0sFoswiki::Plugins::ExpandTopicContentPlugin::::_entityEncodeFoswiki::Plugins::ExpandTopicContentPlugin::_entityEncode
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 default license and copyright information
2=begin TML
3
4---+ package ExpandTopicContentPlugin
5
6This plugin implements the macro EXPANDTOPIC which fetches the content of a
7a given topic and returns the content a bit like an INCLUDE does.
8
9The following is done to the expanded topic.
10
11 * If the parameter expand is set to 'create' all macros inside sections of
12 type 'expandvariables' are expanded the same way, and according to the
13 same rules as when a template topic is expanded when creating a new topic.
14 * If the parameter expand is set to 'all' all macros are expanded in the
15 scope of the expanded topic.
16 * If the parameter expand is set to 'none' no macros are expanded (they will
17 be later in the context of the parent topic unless encoded).
18 * Defined preferences in the expanded topic are not defined in the including
19 parent topic. Preferences defined in the parent are however valid in the
20 expanded topic.
21 * If the parameter encode is set to 'entity' the entire expanded topic is
22 entity encoded so it can be contained inside a hidden html text field.
23 * If the parameter encode is set to 'hidden' the EXPANDTOPIC returns nothing.
24 This can be quite useful if the expanded topic contains Macros from
25 plugins that either performs an action or defines macros that are
26 accessible from the parent topic
27
28The applications for this plugin are
29
30 * Enable overwriting existing topics by the expanded content of a template
31 topic. E.g. to create flat static base line document that can be updated
32 from a template topic that contains formatted searches, INCLUDEs, and
33 other macros. This is done by making a creator topic that contains
34 an HTML form that targets the base line topic and contains a hidden
35 input field with .. <input type="hidden" name="text"
36 value="%EXPANDTOPIC{"TemplateTopic" encode="entiry"}% />
37 * INCLUDE a topic without actually including the content in the rendered
38 output but take advantage of the actions a plugin takes on the included
39 topic. An example can be to include a schedule created by TimeCalcPlugin
40 and display selected stored time values in the parent topic.
41 Note that the parent topic cannot use preferences defined in the expanded
42 topic. They are only valid in content taken from the expanded topic.
43
44=cut
45
46package Foswiki::Plugins::ExpandTopicContentPlugin;
47
48# Always use strict to enforce variable scoping
49232µs240µs
# spent 27µs (14+13) within Foswiki::Plugins::ExpandTopicContentPlugin::BEGIN@49 which was called: # once (14µs+13µs) by Foswiki::Plugin::BEGIN@2.13 at line 49
use strict;
# spent 27µs making 1 call to Foswiki::Plugins::ExpandTopicContentPlugin::BEGIN@49 # spent 13µs making 1 call to strict::import
50225µs221µs
# spent 15µs (9+6) within Foswiki::Plugins::ExpandTopicContentPlugin::BEGIN@50 which was called: # once (9µs+6µs) by Foswiki::Plugin::BEGIN@2.13 at line 50
use warnings;
# spent 15µs making 1 call to Foswiki::Plugins::ExpandTopicContentPlugin::BEGIN@50 # spent 6µs making 1 call to warnings::import
51
52219µs13µs
# spent 3µs within Foswiki::Plugins::ExpandTopicContentPlugin::BEGIN@52 which was called: # once (3µs+0s) by Foswiki::Plugin::BEGIN@2.13 at line 52
use Foswiki::Func (); # The plugins API
53218µs13µs
# spent 3µs within Foswiki::Plugins::ExpandTopicContentPlugin::BEGIN@53 which was called: # once (3µs+0s) by Foswiki::Plugin::BEGIN@2.13 at line 53
use Foswiki::Plugins (); # For the API version
542583µs13µs
# spent 3µs within Foswiki::Plugins::ExpandTopicContentPlugin::BEGIN@54 which was called: # once (3µs+0s) by Foswiki::Plugin::BEGIN@2.13 at line 54
use Foswiki::Time (); # Time API
55
56# $VERSION is referred to by Foswiki, and is the only global variable that
57# *must* exist in this package.
581700nsour $VERSION = '1.1'; # Do not change this
591300nsour $RELEASE = '1.1'; # Change this. Keep it in X.Y format
601200nsour $SHORTDESCRIPTION = 'Expands all macros and expandvariables type sections of a topic and return the raw markup';
611200nsour $NO_PREFS_IN_TOPIC = 1;
62
63=begin TML
64
65---++ initPlugin($topic, $web, $user) -> $boolean
66 * =$topic= - the name of the topic in the current CGI query
67 * =$web= - the name of the web in the current CGI query
68 * =$user= - the login name of the user
69 * =$installWeb= - the name of the web the plugin topic is in
70 (usually the same as =$Foswiki::cfg{SystemWebName}=)
71
72*REQUIRED*
73
74Called to initialise the plugin. If everything is OK, should return
75a non-zero value. On non-fatal failure, should write a message
76using =Foswiki::Func::writeWarning= and return 0. In this case
77%<nop>FAILEDPLUGINS% will indicate which plugins failed.
78
79In the case of a catastrophic failure that will prevent the whole
80installation from working safely, this handler may use 'die', which
81will be trapped and reported in the browser.
82
83__Note:__ Please align macro names with the Plugin name, e.g. if
84your Plugin is called !FooBarPlugin, name macros FOOBAR and/or
85FOOBARSOMETHING. This avoids namespace issues.
86
87=cut
88
89
# spent 104µs (36+68) within Foswiki::Plugins::ExpandTopicContentPlugin::initPlugin which was called: # once (36µs+68µs) 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 {
9013µs my ( $topic, $web, $user, $installWeb ) = @_;
91
92 # check for Plugins.pm versions
93120µs111µs if ( $Foswiki::Plugins::VERSION < 2.0 ) {
# spent 11µs making 1 call to version::vxs::VCMP
94 Foswiki::Func::writeWarning( 'Version mismatch between ',
95 __PACKAGE__, ' and Plugins.pm' );
96 return 0;
97 }
98
99 # Register the _EXAMPLETAG function to handle %EXAMPLETAG{...}%
100 # This will be called whenever %EXAMPLETAG% or %EXAMPLETAG{...}% is
101 # seen in the topic text.
10214µs132µs Foswiki::Func::registerTagHandler( 'EXPANDTOPIC', \&_EXPANDTOPIC );
# spent 32µs making 1 call to Foswiki::Func::registerTagHandler
103
10414µs125µs Foswiki::Func::registerTagHandler( 'REVISIONATTIME', \&_REVISIONATTIME );
# spent 25µs making 1 call to Foswiki::Func::registerTagHandler
105
106 # Plugin correctly initialized
10716µs return 1;
108}
109
110sub _entityEncode {
111 my ( $text ) = @_;
112
113 # encode all non-printable 7-bit chars (< \x1f),
114 # except \n (\xa) and \r (\xd)
115 # encode HTML special characters '>', '<', '&', ''' and '"'.
116 # encode TML special characters '%', '|', '[', ']', '@', '_',
117 # '*', and '='
118 $text =~
119 s/([[\x01-\x09\x0b\x0c\x0e-\x1f"%&'*<=>@[_\|\n])/'&#'.ord($1).';'/ge;
120 return $text;
121}
122
123# The function used to handle the %EXAMPLETAG{...}% macro
124# You would have one of these for each macro you want to process.
125sub _EXPANDTOPIC {
126 my($session, $params, $topic, $web, $topicObject) = @_;
127 # $session - a reference to the Foswiki session object
128 # (you probably won't need it, but documented in Foswiki.pm)
129 # $params= - a reference to a Foswiki::Attrs object containing
130 # parameters.
131 # This can be used as a simple hash that maps parameter names
132 # to values, with _DEFAULT being the name for the default
133 # (unnamed) parameter.
134 # $topic - name of the topic in the query
135 # $web - name of the web in the query
136 # $topicObject - a reference to a Foswiki::Meta object containing the
137 # topic the macro is being rendered in (new for foswiki 1.1.x)
138 # Return: the result of processing the macro. This will replace the
139 # macro call in the final text.
140
141 # For example, %EXAMPLETAG{'hamburger' sideorder="onions"}%
142 # $params->{_DEFAULT} will be 'hamburger'
143 # $params->{sideorder} will be 'onions'
144
145 my $sourceWeb = $params->{web} || $web;
146 my $sourceTopic = $params->{_DEFAULT} || $topic;
147 my $encode = $params->{encode} || 'none';
148 my $expand = $params->{expand} || 'all';
149 my $rev = $params->{rev} || ''; # 0 becomes '' which is what we want
150
151 ( $sourceWeb, $sourceTopic ) =
152 Foswiki::Func::normalizeWebTopicName( $sourceWeb, $sourceTopic );
153
154 my $currentWikiName = Foswiki::Func::getWikiName( );
155
156 unless ( Foswiki::Func::topicExists( $sourceWeb, $sourceTopic ) ) {
157 return 'Topic does not exist';
158 }
159
160 unless ( Foswiki::Func::checkAccessPermission( 'VIEW', $currentWikiName,
161 undef, $sourceTopic, $sourceWeb ) ) {
162 return 'Access to topic not allowed';
163 }
164
165 my ( undef, $text ) = Foswiki::Func::readTopic( $sourceWeb, $sourceTopic, $rev );
166
167 # By pushing the topic context we get preferences in the expanded topics
168 # set in its local context. Something you cannot do with INCLUDE
169 Foswiki::Func::pushTopicContext( $sourceWeb, $sourceTopic );
170
171 # Expand like creating new topic from templatetopic
172 if ( $expand eq 'create' ) {
173 $text = Foswiki::Func::expandVariablesOnTopicCreation( $text );
174 }
175 elsif ( $expand eq 'all' ) {
176 $text = Foswiki::Func::expandCommonVariables( $text );
177 }
178 #else 'none'
179
180 # It is tempting to keep the pushed context so preferences are available
181 # by the parent but that creates a lot of trouble like cancelling edit
182 # ends up in the expanded topic. We must pop back the topic context
183 Foswiki::Func::popTopicContext;
184
185 if ( $encode eq 'entity' ) {
186 $text = _entityEncode( $text );
187 }
188 elsif ( $encode eq 'hide' ) {
189 $text = '';
190 }
191
192 return $text;
193}
194
195sub _REVISIONATTIME {
196 my($session, $params, $topic, $web, $topicObject) = @_;
197
198 my $targetWeb = $params->{web} || $web;
199 my $targetTopic = $params->{_DEFAULT} || $topic;
200 my $targetTime = $params->{time} || '+0';
201
202 $targetTime =~ s/^\s+//; #remove leading spaces
203 $targetTime =~ s/\s+$//; #remove trailing spaces
204
205 if ( $targetTime =~ /^[+-]/ ) {
206 $targetTime = time() + $targetTime;
207 }
208 else {
209 # If the user asks for a revision on a given date without a time
210 # We assume the user will want the revision no matter what time of
211 # the day it was saved, so we change the time to one minute to
212 # midnight end of the given day.
213 # We will only do this for the DD Mmm YYYY format. Iso time will
214 # be assumed accurate
215 if ( $targetTime =~ /(\d+)[-\s]+([a-z]{3})[-\s]+(\d+)$/i ) {
216 $targetTime = $targetTime . " 23:59";
217 }
218 $targetTime = Foswiki::Time::parseTime( $targetTime );
219 }
220
221 my $targetRev =
222 Foswiki::Func::getRevisionAtTime( $targetWeb, $targetTopic, $targetTime );
223
224 # If the time is invalid it is probably a date older than the topic
225 # Then the most useful value is to return rev 1
226 return '0' unless defined( $targetRev );
227
228 $targetRev =~ s/\d+\.(\d+)/$1/o;
229
230 return $targetRev;
231}
232
23313µs1;
234
235__END__