← Index
NYTProf Performance Profile   « line view »
For ./view
  Run on Fri Jul 31 19:05:14 2015
Reported on Fri Jul 31 19:08:09 2015

Filename/var/www/foswiki11/lib/Foswiki/Func.pm
StatementsExecuted 163730 statements in 534ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
8133665794ms1.85sFoswiki::Func::::normalizeWebTopicNameFoswiki::Func::normalizeWebTopicName
3337.27ms7.39msFoswiki::Func::::getPluginPreferencesValueFoswiki::Func::getPluginPreferencesValue
131362.50ms3.10msFoswiki::Func::::registerRESTHandlerFoswiki::Func::registerRESTHandler
444414857µs1.09msFoswiki::Func::::registerTagHandlerFoswiki::Func::registerTagHandler
503313430µs2.07msFoswiki::Func::::getPreferencesValueFoswiki::Func::getPreferencesValue
6766267µs318µsFoswiki::Func::::getContextFoswiki::Func::getContext
2633149µs173µsFoswiki::Func::::getRequestObjectFoswiki::Func::getRequestObject
741146µs228µsFoswiki::Func::::_checkWTAFoswiki::Func::_checkWTA
2487124µs279µsFoswiki::Func::::getCgiQueryFoswiki::Func::getCgiQuery
221118µs8.35sFoswiki::Func::::getListOfWebsFoswiki::Func::getListOfWebs
14139117µs971µsFoswiki::Func::::getPreferencesFlagFoswiki::Func::getPreferencesFlag
411112µs8.35sFoswiki::Func::::__ANON__[:611]Foswiki::Func::__ANON__[:611]
12105110µs356µsFoswiki::Func::::addToZoneFoswiki::Func::addToZone
22286µs9.53msFoswiki::Func::::readTopicTextFoswiki::Func::readTopicText
22144µs1.21msFoswiki::Func::::expandCommonVariablesFoswiki::Func::expandCommonVariables
11139µs1.07msFoswiki::Func::::checkAccessPermissionFoswiki::Func::checkAccessPermission
22238µs229µsFoswiki::Func::::getPluginPreferencesFlagFoswiki::Func::getPluginPreferencesFlag
11134µs692µsFoswiki::Func::::readTopicFoswiki::Func::readTopic
11132µs169µsFoswiki::Func::::topicExistsFoswiki::Func::topicExists
11132µs58µsFoswiki::Func::::setSessionValueFoswiki::Func::setSessionValue
22130µs149µsFoswiki::Func::::extractParametersFoswiki::Func::extractParameters
32125µs113µsFoswiki::Func::::_validateWTAFoswiki::Func::_validateWTA
11122µs34µsFoswiki::Func::::clearSessionValueFoswiki::Func::clearSessionValue
11119µs134µsFoswiki::Func::::getWorkAreaFoswiki::Func::getWorkArea
11117µs28µsFoswiki::Func::::getCanonicalUserIDFoswiki::Func::getCanonicalUserID
11115µs27µsFoswiki::Func::::BEGIN@53Foswiki::Func::BEGIN@53
66114µs14µsFoswiki::Func::::getRegularExpressionFoswiki::Func::getRegularExpression
44412µs12µsFoswiki::Func::::getPubUrlPathFoswiki::Func::getPubUrlPath
2219µs20µsFoswiki::Func::::isTrueFoswiki::Func::isTrue
1119µs10µsFoswiki::Func::::getUrlHostFoswiki::Func::getUrlHost
1119µs21µsFoswiki::Func::::BEGIN@58Foswiki::Func::BEGIN@58
1118µs13µsFoswiki::Func::::BEGIN@54Foswiki::Func::BEGIN@54
1118µs108µsFoswiki::Func::::BEGIN@57Foswiki::Func::BEGIN@57
1114µs4µsFoswiki::Func::::BEGIN@60Foswiki::Func::BEGIN@60
1113µs3µsFoswiki::Func::::BEGIN@55Foswiki::Func::BEGIN@55
1113µs3µsFoswiki::Func::::BEGIN@61Foswiki::Func::BEGIN@61
1113µs3µsFoswiki::Func::::BEGIN@64Foswiki::Func::BEGIN@64
1113µs3µsFoswiki::Func::::BEGIN@62Foswiki::Func::BEGIN@62
1113µs3µsFoswiki::Func::::BEGIN@63Foswiki::Func::BEGIN@63
0000s0sFoswiki::Func::::__ANON__[:1189]Foswiki::Func::__ANON__[:1189]
0000s0sFoswiki::Func::::__ANON__[:1291]Foswiki::Func::__ANON__[:1291]
0000s0sFoswiki::Func::::__ANON__[:1759]Foswiki::Func::__ANON__[:1759]
0000s0sFoswiki::Func::::__ANON__[:1762]Foswiki::Func::__ANON__[:1762]
0000s0sFoswiki::Func::::__ANON__[:2363]Foswiki::Func::__ANON__[:2363]
0000s0sFoswiki::Func::::__ANON__[:3579]Foswiki::Func::__ANON__[:3579]
0000s0sFoswiki::Func::::__ANON__[:3587]Foswiki::Func::__ANON__[:3587]
0000s0sFoswiki::Func::::__ANON__[:707]Foswiki::Func::__ANON__[:707]
0000s0sFoswiki::Func::::addToHEADFoswiki::Func::addToHEAD
0000s0sFoswiki::Func::::addUserToGroupFoswiki::Func::addUserToGroup
0000s0sFoswiki::Func::::attachmentExistsFoswiki::Func::attachmentExists
0000s0sFoswiki::Func::::checkDependenciesFoswiki::Func::checkDependencies
0000s0sFoswiki::Func::::checkTopicEditLockFoswiki::Func::checkTopicEditLock
0000s0sFoswiki::Func::::copyAttachmentFoswiki::Func::copyAttachment
0000s0sFoswiki::Func::::createWebFoswiki::Func::createWeb
0000s0sFoswiki::Func::::decodeFormatTokensFoswiki::Func::decodeFormatTokens
0000s0sFoswiki::Func::::eachChangeSinceFoswiki::Func::eachChangeSince
0000s0sFoswiki::Func::::eachEventSinceFoswiki::Func::eachEventSince
0000s0sFoswiki::Func::::eachGroupFoswiki::Func::eachGroup
0000s0sFoswiki::Func::::eachGroupMemberFoswiki::Func::eachGroupMember
0000s0sFoswiki::Func::::eachMembershipFoswiki::Func::eachMembership
0000s0sFoswiki::Func::::eachUserFoswiki::Func::eachUser
0000s0sFoswiki::Func::::emailToWikiNamesFoswiki::Func::emailToWikiNames
0000s0sFoswiki::Func::::expandTemplateFoswiki::Func::expandTemplate
0000s0sFoswiki::Func::::expandVariablesOnTopicCreationFoswiki::Func::expandVariablesOnTopicCreation
0000s0sFoswiki::Func::::extractNameValuePairFoswiki::Func::extractNameValuePair
0000s0sFoswiki::Func::::formatGmTimeFoswiki::Func::formatGmTime
0000s0sFoswiki::Func::::formatTimeFoswiki::Func::formatTime
0000s0sFoswiki::Func::::getAttachmentListFoswiki::Func::getAttachmentList
0000s0sFoswiki::Func::::getDataDirFoswiki::Func::getDataDir
0000s0sFoswiki::Func::::getDefaultUserNameFoswiki::Func::getDefaultUserName
0000s0sFoswiki::Func::::getExternalResourceFoswiki::Func::getExternalResource
0000s0sFoswiki::Func::::getMainWebnameFoswiki::Func::getMainWebname
0000s0sFoswiki::Func::::getOopsUrlFoswiki::Func::getOopsUrl
0000s0sFoswiki::Func::::getPubDirFoswiki::Func::getPubDir
0000s0sFoswiki::Func::::getPublicWebListFoswiki::Func::getPublicWebList
0000s0sFoswiki::Func::::getRevisionAtTimeFoswiki::Func::getRevisionAtTime
0000s0sFoswiki::Func::::getRevisionInfoFoswiki::Func::getRevisionInfo
0000s0sFoswiki::Func::::getScriptUrlFoswiki::Func::getScriptUrl
0000s0sFoswiki::Func::::getScriptUrlPathFoswiki::Func::getScriptUrlPath
0000s0sFoswiki::Func::::getSessionKeysFoswiki::Func::getSessionKeys
0000s0sFoswiki::Func::::getSessionValueFoswiki::Func::getSessionValue
0000s0sFoswiki::Func::::getSkinFoswiki::Func::getSkin
0000s0sFoswiki::Func::::getTopicListFoswiki::Func::getTopicList
0000s0sFoswiki::Func::::getTwikiWebnameFoswiki::Func::getTwikiWebname
0000s0sFoswiki::Func::::getViewUrlFoswiki::Func::getViewUrl
0000s0sFoswiki::Func::::getWikiNameFoswiki::Func::getWikiName
0000s0sFoswiki::Func::::getWikiToolNameFoswiki::Func::getWikiToolName
0000s0sFoswiki::Func::::getWikiUserNameFoswiki::Func::getWikiUserName
0000s0sFoswiki::Func::::internalLinkFoswiki::Func::internalLink
0000s0sFoswiki::Func::::isAnAdminFoswiki::Func::isAnAdmin
0000s0sFoswiki::Func::::isGroupFoswiki::Func::isGroup
0000s0sFoswiki::Func::::isGroupMemberFoswiki::Func::isGroupMember
0000s0sFoswiki::Func::::isGuestFoswiki::Func::isGuest
0000s0sFoswiki::Func::::isValidTopicNameFoswiki::Func::isValidTopicName
0000s0sFoswiki::Func::::isValidWebNameFoswiki::Func::isValidWebName
0000s0sFoswiki::Func::::isValidWikiWordFoswiki::Func::isValidWikiWord
0000s0sFoswiki::Func::::loadTemplateFoswiki::Func::loadTemplate
0000s0sFoswiki::Func::::moveAttachmentFoswiki::Func::moveAttachment
0000s0sFoswiki::Func::::moveTopicFoswiki::Func::moveTopic
0000s0sFoswiki::Func::::moveWebFoswiki::Func::moveWeb
0000s0sFoswiki::Func::::permissionsSetFoswiki::Func::permissionsSet
0000s0sFoswiki::Func::::popTopicContextFoswiki::Func::popTopicContext
0000s0sFoswiki::Func::::pushTopicContextFoswiki::Func::pushTopicContext
0000s0sFoswiki::Func::::queryFoswiki::Func::query
0000s0sFoswiki::Func::::readAttachmentFoswiki::Func::readAttachment
0000s0sFoswiki::Func::::readFileFoswiki::Func::readFile
0000s0sFoswiki::Func::::readTemplateFoswiki::Func::readTemplate
0000s0sFoswiki::Func::::redirectCgiQueryFoswiki::Func::redirectCgiQuery
0000s0sFoswiki::Func::::registerMETAFoswiki::Func::registerMETA
0000s0sFoswiki::Func::::removeUserFromGroupFoswiki::Func::removeUserFromGroup
0000s0sFoswiki::Func::::renderTextFoswiki::Func::renderText
0000s0sFoswiki::Func::::sanitizeAttachmentNameFoswiki::Func::sanitizeAttachmentName
0000s0sFoswiki::Func::::saveAttachmentFoswiki::Func::saveAttachment
0000s0sFoswiki::Func::::saveFileFoswiki::Func::saveFile
0000s0sFoswiki::Func::::saveTopicFoswiki::Func::saveTopic
0000s0sFoswiki::Func::::saveTopicTextFoswiki::Func::saveTopicText
0000s0sFoswiki::Func::::searchInWebContentFoswiki::Func::searchInWebContent
0000s0sFoswiki::Func::::sendEmailFoswiki::Func::sendEmail
0000s0sFoswiki::Func::::setPreferencesValueFoswiki::Func::setPreferencesValue
0000s0sFoswiki::Func::::setTopicEditLockFoswiki::Func::setTopicEditLock
0000s0sFoswiki::Func::::spaceOutWikiWordFoswiki::Func::spaceOutWikiWord
0000s0sFoswiki::Func::::summariseChangesFoswiki::Func::summariseChanges
0000s0sFoswiki::Func::::userToWikiNameFoswiki::Func::userToWikiName
0000s0sFoswiki::Func::::webExistsFoswiki::Func::webExists
0000s0sFoswiki::Func::::wikiToEmailFoswiki::Func::wikiToEmail
0000s0sFoswiki::Func::::wikiToUserNameFoswiki::Func::wikiToUserName
0000s0sFoswiki::Func::::wikinameToEmailsFoswiki::Func::wikinameToEmails
0000s0sFoswiki::Func::::writeDebugFoswiki::Func::writeDebug
0000s0sFoswiki::Func::::writeEventFoswiki::Func::writeEvent
0000s0sFoswiki::Func::::writeHeaderFoswiki::Func::writeHeader
0000s0sFoswiki::Func::::writeWarningFoswiki::Func::writeWarning
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
2
3=begin TML
4
5---+ package Foswiki::Func
6
7_Interface for Foswiki extensions developers_
8
9This module defines the main interfaces that extensions
10can use to interact with the Foswiki engine and content.
11
12Refer to =lib/Foswiki/Plugins/EmptyPlugin.pm= for a template Plugin
13and starter documentation on how to write a Plugin.
14
15Plugins should *only* call methods in packages documented in
16System.DevelopingPlugins. If you use
17functions in other Foswiki libraries you risk creating a security hole, and
18you will probably need to change your plugin when you upgrade Foswiki.
19
20*Since:* _date_ indicates where functions or parameters have been added since
21the baseline of the API (Foswiki 1.0.0). The _date_ indicates the
22earliest date of a Foswiki release that will support that function or
23parameter. See Foswiki:Download.ReleaseDates for version release dates.
24
25*Deprecated* _date_ indicates where a function or parameters has been
26[[http://en.wikipedia.org/wiki/Deprecation][deprecated]]. Deprecated
27functions will still work, though they should
28_not_ be called in new plugins and should be replaced in older plugins
29as soon as possible. Deprecated parameters are simply ignored in Foswiki
30releases after _date_.
31
32*Until* _date_ indicates where a function or parameter has been removed.
33The _date_ indicates the latest date at which Foswiki releases still supported
34the function or parameter.
35
36Note that the =Foswiki::Func= API should always be the first place extension
37authors look for methods. Certain other lower-level APIs are also exposed
38by the core, but those APIs should only be called if there is no alternative
39available through =Foswiki::Func=. The APIs in question are documented in
40System.DevelopingPlugins.
41
42=cut
43
44# THIS PACKAGE IS PART OF THE PUBLISHED API USED BY EXTENSION AUTHORS.
45# DO NOT CHANGE THE EXISTING APIS (well thought out extensions are OK)
46# AND ENSURE ALL POD DOCUMENTATION IS COMPLETE AND ACCURATE.
47#
48# Deprecated functions should not be removed, but should be moved to to the
49# deprecated functions section.
50
51package Foswiki::Func;
52
53225µs240µs
# spent 27µs (15+12) within Foswiki::Func::BEGIN@53 which was called: # once (15µs+12µs) by Foswiki::UserMapping::BEGIN@39 at line 53
use strict;
# spent 27µs making 1 call to Foswiki::Func::BEGIN@53 # spent 12µs making 1 call to strict::import
54221µs218µs
# spent 13µs (8+5) within Foswiki::Func::BEGIN@54 which was called: # once (8µs+5µs) by Foswiki::UserMapping::BEGIN@39 at line 54
use warnings;
# spent 13µs making 1 call to Foswiki::Func::BEGIN@54 # spent 5µs making 1 call to warnings::import
55222µs13µs
# spent 3µs within Foswiki::Func::BEGIN@55 which was called: # once (3µs+0s) by Foswiki::UserMapping::BEGIN@39 at line 55
use Scalar::Util ();
# spent 3µs making 1 call to Foswiki::Func::BEGIN@55
56
57228µs2208µs
# spent 108µs (8+100) within Foswiki::Func::BEGIN@57 which was called: # once (8µs+100µs) by Foswiki::UserMapping::BEGIN@39 at line 57
use Error qw( :try );
# spent 108µs making 1 call to Foswiki::Func::BEGIN@57 # spent 100µs making 1 call to Error::import
58227µs233µs
# spent 21µs (9+12) within Foswiki::Func::BEGIN@58 which was called: # once (9µs+12µs) by Foswiki::UserMapping::BEGIN@39 at line 58
use Assert;
# spent 21µs making 1 call to Foswiki::Func::BEGIN@58 # spent 12µs making 1 call to Assert::import
59
60219µs14µs
# spent 4µs within Foswiki::Func::BEGIN@60 which was called: # once (4µs+0s) by Foswiki::UserMapping::BEGIN@39 at line 60
use Foswiki ();
# spent 4µs making 1 call to Foswiki::Func::BEGIN@60
61224µs13µs
# spent 3µs within Foswiki::Func::BEGIN@61 which was called: # once (3µs+0s) by Foswiki::UserMapping::BEGIN@39 at line 61
use Foswiki::Plugins ();
# spent 3µs making 1 call to Foswiki::Func::BEGIN@61
62218µs13µs
# spent 3µs within Foswiki::Func::BEGIN@62 which was called: # once (3µs+0s) by Foswiki::UserMapping::BEGIN@39 at line 62
use Foswiki::Meta ();
# spent 3µs making 1 call to Foswiki::Func::BEGIN@62
63221µs13µs
# spent 3µs within Foswiki::Func::BEGIN@63 which was called: # once (3µs+0s) by Foswiki::UserMapping::BEGIN@39 at line 63
use Foswiki::AccessControlException ();
# spent 3µs making 1 call to Foswiki::Func::BEGIN@63
6427.27ms13µs
# spent 3µs within Foswiki::Func::BEGIN@64 which was called: # once (3µs+0s) by Foswiki::UserMapping::BEGIN@39 at line 64
use Foswiki::Sandbox ();
# spent 3µs making 1 call to Foswiki::Func::BEGIN@64
65
66# Given $web, $web and $topic, or $web $topic and $attachment, validate
67# and untaint each of them and return. If any fails to validate it will
68# be returned as undef.
69
# spent 228µs (146+82) within Foswiki::Func::_checkWTA which was called 7 times, avg 33µs/call: # 3 times (48µs+40µs) by Foswiki::Func::_validateWTA at line 100, avg 29µs/call # 2 times (44µs+8µs) by Foswiki::Func::getListOfWebs at line 1471, avg 26µs/call # once (39µs+19µs) by Foswiki::Func::topicExists at line 1563 # once (16µs+14µs) by Foswiki::Func::checkAccessPermission at line 1404
sub _checkWTA {
70716µs my ( $web, $topic, $attachment ) = @_;
7176µs if ( defined $topic ) {
7256µs54µs ASSERT($Foswiki::Plugins::SESSION) if DEBUG;
# spent 4µs making 5 calls to Assert::ASSERTS_OFF, avg 880ns/call
73515µs557µs ( $web, $topic ) =
# spent 57µs making 5 calls to Foswiki::normalizeWebTopicName, avg 11µs/call
74 $Foswiki::Plugins::SESSION->normalizeWebTopicName( $web, $topic );
75 }
76750µs717µs if ( Scalar::Util::tainted($web) ) {
# spent 17µs making 7 calls to Scalar::Util::tainted, avg 2µs/call
77 $web = Foswiki::Sandbox::untaint( $web,
78 \&Foswiki::Sandbox::validateWebName );
79 }
80720µs return ($web) unless defined $web && defined $topic;
81
82518µs53µs if ( Scalar::Util::tainted($topic) ) {
# spent 3µs making 5 calls to Scalar::Util::tainted, avg 640ns/call
83 $topic = Foswiki::Sandbox::untaint( $topic,
84 \&Foswiki::Sandbox::validateTopicName );
85 }
86523µs return ( $web, $topic ) unless defined $topic && defined $attachment;
87
88 if ( Scalar::Util::tainted($attachment) ) {
89 $attachment = Foswiki::Sandbox::untaint( $attachment,
90 \&Foswiki::Sandbox::validateAttachmentName );
91 }
92 return ( $web, $topic, $attachment );
93
94}
95
96# Validate a web.topic.attachment and throw an exception if the
97# validation fails
98
# spent 113µs (25+88) within Foswiki::Func::_validateWTA which was called 3 times, avg 38µs/call: # 2 times (14µs+54µs) by Foswiki::Func::expandCommonVariables at line 2527, avg 34µs/call # once (11µs+34µs) by Foswiki::Func::readTopic at line 1591
sub _validateWTA {
9934µs my ( $web, $topic, $attachment ) = @_;
10037µs388µs my ( $w, $t, $a ) = _checkWTA( $web, $topic, $attachment );
# spent 88µs making 3 calls to Foswiki::Func::_checkWTA, avg 29µs/call
10131µs die 'Invalid web' if ( defined $web && !defined $w );
10231µs die 'Invalid topic' if ( defined $topic && !defined $t );
1033500ns die 'Invalid attachment' if ( defined $attachment && !defined $a );
104313µs return ( $w, $t, $a );
105}
106
107=begin TML
108
109---++ Environment
110
111=cut
112
113=begin TML
114
115---+++ getSkin( ) -> $skin
116
117Get the skin path, set by the =SKIN= and =COVER= preferences variables or the =skin= and =cover= CGI parameters
118
119Return: =$skin= Comma-separated list of skins, e.g. ='gnu,tartan'=. Empty string if none.
120
121=cut
122
123sub getSkin {
124 ASSERT($Foswiki::Plugins::SESSION) if DEBUG;
125
126 return $Foswiki::Plugins::SESSION->getSkin();
127}
128
129=begin TML
130
131---+++ getUrlHost( ) -> $host
132
133Get protocol, domain and optional port of script URL
134
135Return: =$host= URL host, e.g. ="http://example.com:80"=
136
137=cut
138
139
# spent 10µs (9+1) within Foswiki::Func::getUrlHost which was called: # once (9µs+1µs) by Foswiki::Plugins::RenderListPlugin::initPlugin at line 67 of /var/www/foswiki11/lib/Foswiki/Plugins/RenderListPlugin.pm
sub getUrlHost {
14012µs11µs ASSERT($Foswiki::Plugins::SESSION) if DEBUG;
# spent 1µs making 1 call to Assert::ASSERTS_OFF
141
14216µs return $Foswiki::Plugins::SESSION->{urlHost};
143}
144
145=begin TML
146
147---+++ getScriptUrl( $web, $topic, $script, ... ) -> $url
148
149Compose fully qualified URL
150 * =$web= - Web name, e.g. ='Main'=
151 * =$topic= - Topic name, e.g. ='WebNotify'=
152 * =$script= - Script name, e.g. ='view'=
153 * =...= - an arbitrary number of name=>value parameter pairs that will be url-encoded and added to the url. The special parameter name '#' is reserved for specifying an anchor. e.g. <tt>getScriptUrl('x','y','view','#'=>'XXX',a=>1,b=>2)</tt> will give <tt>.../view/x/y?a=1&b=2#XXX</tt>
154
155Return: =$url= URL, e.g. ="http://example.com:80/cgi-bin/view.pl/Main/WebNotify"=
156
157*Examples:*
158<verbatim class="perl">
159my $url;
160# $url eq 'http://wiki.example.org/url/to/bin'
161$url = Foswiki::Func::getScriptUrl();
162# $url eq 'http://wiki.example.org/url/to/bin/edit'
163$url = Foswiki::Func::getScriptUrl(undef, undef, 'edit');
164# $url eq 'http://wiki.example.org/url/to/bin/edit/Web/Topic'
165$url = Foswiki::Func::getScriptUrl('Web', 'Topic', 'edit');</verbatim>
166
167=cut
168
169sub getScriptUrl {
170 my $web = shift;
171 my $topic = shift;
172 my $script = shift;
173 ASSERT($Foswiki::Plugins::SESSION) if DEBUG;
174
175 return $Foswiki::Plugins::SESSION->getScriptUrl( 1, $script, $web, $topic,
176 @_ );
177}
178
179=begin TML
180
181---+++ getScriptUrlPath( $web, $topic, $script, ... ) -> $path
182
183Compose absolute URL path. See Foswiki::Func::getScriptUrl
184
185*Examples:*
186<verbatim class="perl">
187my $path;
188# $path eq '/path/to/bin'
189$path = Foswiki::Func::getScriptUrlPath();
190# $path eq '/path/to/bin/edit'
191$path = Foswiki::Func::getScriptUrlPath(undef, undef, 'edit');
192# $path eq '/path/to/bin/edit/Web/Topic'
193$path = Foswiki::Func::getScriptUrlPath('Web', 'Topic', 'edit');</verbatim>
194
195*Since:* 19 Jan 2012 (when called without parameters, this function is
196backwards-compatible with the old version which was deprecated 28 Nov 2008).
197
198=cut
199
200sub getScriptUrlPath {
201 my $web = shift;
202 my $topic = shift;
203 my $script = shift;
204 ASSERT($Foswiki::Plugins::SESSION) if DEBUG;
205
206 return $Foswiki::Plugins::SESSION->getScriptUrl( 0, $script, $web, $topic,
207 @_ );
208}
209
210=begin TML
211
212---+++ getViewUrl( $web, $topic ) -> $url
213
214Compose fully qualified view URL
215 * =$web= - Web name, e.g. ='Main'=. The current web is taken if empty
216 * =$topic= - Topic name, e.g. ='WebNotify'=
217Return: =$url= URL, e.g. ="http://example.com:80/cgi-bin/view.pl/Main/WebNotify"=
218
219=cut
220
221sub getViewUrl {
222 my ( $web, $topic ) = @_;
223 ASSERT($Foswiki::Plugins::SESSION) if DEBUG;
224
225 $web ||= $Foswiki::Plugins::SESSION->{webName}
226 || $Foswiki::cfg{UsersWebName};
227 return getScriptUrl( $web, $topic, 'view' );
228}
229
230=begin TML
231
232---+++ getPubUrlPath( ) -> $path
233
234Get pub URL path
235
236Return: =$path= URL path of pub directory, e.g. ="/pub"=
237
238=cut
239
240
# spent 12µs within Foswiki::Func::getPubUrlPath which was called 4 times, avg 3µs/call: # once (4µs+0s) by Foswiki::Plugins::ChecklistPlugin::initDefaults at line 154 of /var/www/foswiki11/lib/Foswiki/Plugins/ChecklistPlugin.pm # once (3µs+0s) by Foswiki::Plugins::TablePlugin::preRenderingHandler at line 43 of /var/www/foswiki11/lib/Foswiki/Plugins/TablePlugin/Core.pm # once (2µs+0s) by Foswiki::Plugins::SmiliesPlugin::initPlugin at line 54 of /var/www/foswiki11/lib/Foswiki/Plugins/SmiliesPlugin.pm # once (2µs+0s) by Foswiki::Plugins::RenderListPlugin::initPlugin at line 67 of /var/www/foswiki11/lib/Foswiki/Plugins/RenderListPlugin.pm
sub getPubUrlPath {
241423µs return $Foswiki::cfg{PubUrlPath};
242}
243
244=begin TML
245
246---+++ getExternalResource( $url ) -> $response
247
248Get whatever is at the other end of a URL (using an HTTP GET request). Will
249only work for encrypted protocols such as =https= if the =LWP= CPAN module is
250installed.
251
252Note that the =$url= may have an optional user and password, as specified by
253the relevant RFC. Any proxy set in =configure= is honoured.
254
255The =$response= is an object that is known to implement the following subset of
256the methods of =LWP::Response=. It may in fact be an =LWP::Response= object,
257but it may also not be if =LWP= is not available, so callers may only assume
258the following subset of methods is available:
259| =code()= |
260| =message()= |
261| =header($field)= |
262| =content()= |
263| =is_error()= |
264| =is_redirect()= |
265
266Note that if LWP is *not* available, this function:
267 1 can only really be trusted for HTTP/1.0 urls. If HTTP/1.1 or another
268 protocol is required, you are *strongly* recommended to =require LWP=.
269 1 Will not parse multipart content
270
271In the event of the server returning an error, then =is_error()= will return
272true, =code()= will return a valid HTTP status code
273as specified in RFC 2616 and RFC 2518, and =message()= will return the
274message that was received from
275the server. In the event of a client-side error (e.g. an unparseable URL)
276then =is_error()= will return true and =message()= will return an explanatory
277message. =code()= will return 400 (BAD REQUEST).
278
279Note: Callers can easily check the availability of other HTTP::Response methods
280as follows:
281
282<verbatim>
283my $response = Foswiki::Func::getExternalResource($url);
284if (!$response->is_error() && $response->isa('HTTP::Response')) {
285 ... other methods of HTTP::Response may be called
286} else {
287 ... only the methods listed above may be called
288}
289</verbatim>
290
291=cut
292
293sub getExternalResource {
294 my ($url) = @_;
295 ASSERT($Foswiki::Plugins::SESSION) if DEBUG;
296 ASSERT( defined $url ) if DEBUG;
297
298 return $Foswiki::Plugins::SESSION->net->getExternalResource($url);
299}
300
301=begin TML
302
303---+++ getRequestObject( ) -> $query
304
305Get the request object. This is a subclass of =Foswiki::Request=. The request
306object can be used to get the parameters passed to the request, either
307via CGI or on the command line (depending on how the script was called).
308
309A =Foswiki::Request= object is largely compatible with a CPAN:CGI object.
310Most of the time, documentation for that class applies directly to
311=Foswiki::Request= objects as well.
312
313Note that this method replaces =getCgiQuery= (which is a synonym for this
314method). Code that is expected to run with pre-1.1 versions of Foswiki
315can continue to call =getCgiQuery= for as long as necessary.
316
317*Since:* 31 Mar 2009
318
319=cut
320
321
# spent 173µs (149+24) within Foswiki::Func::getRequestObject which was called 26 times, avg 7µs/call: # 24 times (134µs+21µs) by Foswiki::Func::getCgiQuery at line 3459, avg 6µs/call # once (11µs+1µs) by Foswiki::Plugins::DirectedGraphPlugin::initPlugin at line 140 of /var/www/foswiki11/lib/Foswiki/Plugins/DirectedGraphPlugin.pm # once (5µs+900ns) by Foswiki::Plugins::PlantUMLPlugin::initPlugin at line 86 of /var/www/foswiki11/lib/Foswiki/Plugins/PlantUMLPlugin.pm
sub getRequestObject {
3222630µs2624µs ASSERT($Foswiki::Plugins::SESSION) if DEBUG;
# spent 24µs making 26 calls to Assert::ASSERTS_OFF, avg 908ns/call
32326110µs return $Foswiki::Plugins::SESSION->{request};
324}
325
326=begin TML
327
328---+++ getSessionKeys() -> @keys
329Get a list of all the names of session variables. The list is unsorted.
330
331Session keys are stored and retrieved using =setSessionValue= and
332=getSessionValue=.
333
334=cut
335
336sub getSessionKeys {
337 ASSERT($Foswiki::Plugins::SESSION) if DEBUG;
338 my $hash =
339 $Foswiki::Plugins::SESSION->getLoginManager()->getSessionValues();
340 return keys %{$hash};
341}
342
343=begin TML
344
345---+++ getSessionValue( $key ) -> $value
346
347Get a session value from the client session module
348 * =$key= - Session key
349Return: =$value= Value associated with key; empty string if not set
350
351=cut
352
353sub getSessionValue {
354
355 # my( $key ) = @_;
356 ASSERT($Foswiki::Plugins::SESSION) if DEBUG;
357
358 return $Foswiki::Plugins::SESSION->getLoginManager()->getSessionValue(@_);
359}
360
361=begin TML
362
363---+++ setSessionValue( $key, $value ) -> $boolean
364
365Set a session value.
366 * =$key= - Session key
367 * =$value= - Value associated with key
368Return: true if function succeeded
369
370=cut
371
372
# spent 58µs (32+26) within Foswiki::Func::setSessionValue which was called: # once (32µs+26µs) by Foswiki::Plugins::DirectedGraphPlugin::initPlugin at line 312 of /var/www/foswiki11/lib/Foswiki/Plugins/DirectedGraphPlugin.pm
sub setSessionValue {
373
374 # my( $key, $value ) = @_;
37512µs11µs ASSERT($Foswiki::Plugins::SESSION) if DEBUG;
# spent 1µs making 1 call to Assert::ASSERTS_OFF
376
377132µs224µs $Foswiki::Plugins::SESSION->getLoginManager()->setSessionValue(@_);
# spent 17µs making 1 call to Foswiki::getLoginManager # spent 7µs making 1 call to Foswiki::LoginManager::setSessionValue
378}
379
380=begin TML
381
382---+++ clearSessionValue( $key ) -> $boolean
383
384Clear a session value that was set using =setSessionValue=.
385 * =$key= - name of value stored in session to be cleared. Note that
386 you *cannot* clear =AUTHUSER=.
387Return: true if the session value was cleared
388
389=cut
390
391
# spent 34µs (22+12) within Foswiki::Func::clearSessionValue which was called: # once (22µs+12µs) by Foswiki::Plugins::DirectedGraphPlugin::initPlugin at line 314 of /var/www/foswiki11/lib/Foswiki/Plugins/DirectedGraphPlugin.pm
sub clearSessionValue {
39212µs11µs ASSERT($Foswiki::Plugins::SESSION) if DEBUG;
# spent 1µs making 1 call to Assert::ASSERTS_OFF
393
394115µs211µs return $Foswiki::Plugins::SESSION->getLoginManager()->clearSessionValue(@_);
# spent 6µs making 1 call to Foswiki::getLoginManager # spent 5µs making 1 call to Foswiki::LoginManager::clearSessionValue
395}
396
397=begin TML
398
399---+++ getContext() -> \%hash
400
401Get a hash of context identifiers representing the currently active
402context.
403
404The context is a set of identifiers that are set
405during specific phases of processing. For example, each of
406the standard scripts in the 'bin' directory each has a context
407identifier - the view script has 'view', the edit script has 'edit'
408etc. So you can easily tell what 'type' of script your Plugin is
409being called within.
410
411A comprehensive list of core context identifiers used by Foswiki is found in
412%SYSTEMWEB%.IfStatements#Context_identifiers. Please be careful not to
413overwrite any of these identifiers!
414
415Context identifiers can be used to communicate between Plugins, and between
416Plugins and templates. For example, in FirstPlugin.pm, you might write:
417<verbatim>
418sub initPlugin {
419 Foswiki::Func::getContext()->{'MyID'} = 1;
420 ...
421</verbatim>
422This can be used in !SecondPlugin.pm like this:
423<verbatim>
424sub initPlugin {
425 if( Foswiki::Func::getContext()->{'MyID'} ) {
426 ...
427 }
428 ...
429</verbatim>
430or in a template, like this:
431<verbatim>
432%TMPL:DEF{"ON"}% Not off %TMPL:END%
433%TMPL:DEF{"OFF"}% Not on %TMPL:END%
434%TMPL:P{context="MyID" then="ON" else="OFF"}%
435</verbatim>
436or in a topic:
437<verbatim>
438%IF{"context MyID" then="MyID is ON" else="MyID is OFF"}%
439</verbatim>
440__Note__: *all* plugins have an *automatically generated* context identifier
441if they are installed and initialised. For example, if the FirstPlugin is
442working, the context ID 'FirstPlugin' will be set.
443
444=cut
445
446
# spent 318µs (267+50) within Foswiki::Func::getContext which was called 67 times, avg 5µs/call: # 56 times (190µs+40µs) by Foswiki::Plugins::JQueryPlugin::Plugins::registerPlugin at line 171 of /var/www/foswiki11/lib/Foswiki/Plugins/JQueryPlugin/Plugins.pm, avg 4µs/call # 7 times (52µs+6µs) by Foswiki::Plugins::WysiwygPlugin::beforeCommonTagsHandler at line 275 of /var/www/foswiki11/lib/Foswiki/Plugins/WysiwygPlugin.pm, avg 8µs/call # once (12µs+1µs) by Foswiki::Plugins::AutoViewTemplatePlugin::initPlugin at line 41 of /var/www/foswiki11/lib/Foswiki/Plugins/AutoViewTemplatePlugin.pm # once (5µs+1µs) by Foswiki::Plugins::DirectedGraphPlugin::initPlugin at line 158 of /var/www/foswiki11/lib/Foswiki/Plugins/DirectedGraphPlugin.pm # once (4µs+900ns) by Foswiki::Plugins::TablePlugin::Core::_parseAttributes at line 284 of /var/www/foswiki11/lib/Foswiki/Plugins/TablePlugin/Core.pm # once (4µs+800ns) by Foswiki::Plugins::PlantUMLPlugin::initPlugin at line 96 of /var/www/foswiki11/lib/Foswiki/Plugins/PlantUMLPlugin.pm
sub getContext {
4476757µs6750µs ASSERT($Foswiki::Plugins::SESSION) if DEBUG;
# spent 50µs making 67 calls to Assert::ASSERTS_OFF, avg 754ns/call
44867187µs return $Foswiki::Plugins::SESSION->{context};
449}
450
451=begin TML
452
453---+++ pushTopicContext($web, $topic)
454 * =$web= - new web
455 * =$topic= - new topic
456Change the Foswiki context, adding the requested =$web.$topic= onto the
457preferences stack. Any preferences found in =$web.$topic= will be used
458in place of preferences previously set in the stack, provided that they
459were not finalized in a lower level. Preferences set in the prior
460=web.topic= are *not* cleared. =$web.$topic= replaces and adds to
461preferences but does not remove preferences that it does not set.
462
463Note that if the new topic is not readable by the logged in user due to
464access control considerations, there will *not* be an exception. It is the
465duty of the caller to check access permissions before changing the topic.
466All other errors will throw an exception.
467
468It is the duty of the caller to restore the original context by calling
469=popTopicContext=.
470
471Note that this call does *not* re-initialise plugins, so if you have used
472global variables to remember the web and topic in =initPlugin=, then those
473values will be unchanged.
474
475=cut
476
477sub pushTopicContext {
478 my $session = $Foswiki::Plugins::SESSION;
479 ASSERT($session) if DEBUG;
480 my ( $web, $topic ) = _validateWTA(@_);
481
482 $session->{prefs}->pushTopicContext( $web, $topic );
483 $session->{webName} = $web;
484 $session->{topicName} = $topic;
485 $session->{prefs}->setInternalPreferences(
486 BASEWEB => $web,
487 BASETOPIC => $topic,
488 INCLUDINGWEB => $web,
489 INCLUDINGTOPIC => $topic
490 );
491}
492
493=begin TML
494
495---+++ popTopicContext()
496
497Returns the Foswiki context to the state it was in before the
498=pushTopicContext= was called.
499
500=cut
501
502sub popTopicContext {
503 my $session = $Foswiki::Plugins::SESSION;
504 ASSERT($session) if DEBUG;
505 ( $session->{webName}, $session->{topicName} ) =
506 $session->{prefs}->popTopicContext();
507}
508
509=begin TML
510
511---++ Registering extensions
512
513Plugins work either by using handlers to manipulate the text being processed,
514or by registering extensions, such as new macros, scripts, or meta-data types.
515
516=cut
517
518=begin TML=
519
520---+++ registerTagHandler( $var, \&fn, $syntax )
521
522Should only be called from initPlugin.
523
524Register a function to handle a simple variable. Handles both %<nop>VAR% and
525%<nop>VAR{...}%. Registered variables are treated the same as internal macros,
526and are expanded at the same time. This is a _lot_ more efficient than using the =commonTagsHandler=.
527 * =$var= - The name of the variable, i.e. the 'MYVAR' part of %<nop>MYVAR%.
528 The variable name *must* match /^[A-Z][A-Z0-9_]*$/ or it won't work.
529 * =\&fn= - Reference to the handler function.
530 * =$syntax= can be 'classic' (the default) or 'context-free'. (context-free may be removed in future)
531 'classic' syntax is appropriate where you want the variable to support classic syntax
532 i.e. to accept the standard =%<nop>MYVAR{ "unnamed" param1="value1" param2="value2" }%= syntax,
533 as well as an unquoted default parameter, such as =%<nop>MYVAR{unquoted parameter}%=.
534 If your variable will only use named parameters, you can use 'context-free' syntax,
535 which supports a more relaxed syntax. For example,
536 %MYVAR{param1=value1, value 2, param3="value 3", param4='value 5"}%
537
538The variable handler function must be of the form:
539<verbatim>
540sub handler(\%session, \%params, $topic, $web, $topicObject)
541</verbatim>
542where:
543 * =\%session= - a reference to the session object (may be ignored)
544 * =\%params= - a reference to a Foswiki::Attrs object containing parameters. This can be used as a simple hash that maps parameter names to values, with _DEFAULT being the name for the default parameter.
545 * =$topic= - name of the topic in the query
546 * =$web= - name of the web in the query
547 * =$topicObject= - is the Foswiki::Meta object for the topic *Since* 2009-03-06
548for example, to execute an arbitrary command on the server, you might do this:
549<verbatim>
550sub initPlugin{
551 Foswiki::Func::registerTagHandler('EXEC', \&boo);
552}
553
554sub boo {
555 my( $session, $params, $topic, $web, $topicObject ) = @_;
556 my $cmd = $params->{_DEFAULT};
557
558 return "NO COMMAND SPECIFIED" unless $cmd;
559
560 my $result = `$cmd 2>&1`;
561 return $params->{silent} ? '' : $result;
562}
563</verbatim>
564would let you do this:
565=%<nop>EXEC{"ps -Af" silent="on"}%=
566
567Registered tags differ from tags implemented using the old approach (text substitution in =commonTagsHandler=) in the following ways:
568 * registered tags are evaluated at the same time as system tags, such as %SERVERTIME. =commonTagsHandler= is only called later, when all system tags have already been expanded (though they are expanded _again_ after =commonTagsHandler= returns).
569 * registered tag names can only contain alphanumerics and _ (underscore)
570 * registering a tag =FRED= defines both =%<nop>FRED{...}%= *and also* =%FRED%=.
571 * registered tag handlers *cannot* return another tag as their only result (e.g. =return '%<nop>SERVERTIME%';=). It won't work.
572
573=cut
574
575
# spent 1.09ms (857µs+233µs) within Foswiki::Func::registerTagHandler which was called 44 times, avg 25µs/call: # once (59µs+16µs) by Foswiki::Plugins::ActionTrackerPlugin::initPlugin at line 31 of /var/www/foswiki11/lib/Foswiki/Plugins/ActionTrackerPlugin.pm # once (29µs+8µs) by Foswiki::Plugins::AttachContentPlugin::initPlugin at line 55 of /var/www/foswiki11/lib/Foswiki/Plugins/AttachContentPlugin.pm # once (17µs+18µs) by Foswiki::Plugins::MultiTopicSavePlugin::initPlugin at line 118 of /var/www/foswiki11/lib/Foswiki/Plugins/MultiTopicSavePlugin.pm # once (26µs+7µs) by Foswiki::Plugins::DelayMacroPlugin::initPlugin at line 85 of /var/www/foswiki11/lib/Foswiki/Plugins/DelayMacroPlugin.pm # once (26µs+6µs) by Foswiki::Plugins::ExpandTopicContentPlugin::initPlugin at line 102 of /var/www/foswiki11/lib/Foswiki/Plugins/ExpandTopicContentPlugin.pm # once (25µs+6µs) by Foswiki::Plugins::JQueryPlugin::initPlugin at line 38 of /var/www/foswiki11/lib/Foswiki/Plugins/JQueryPlugin.pm # once (25µs+6µs) by Foswiki::Plugins::ExtendedWebListPlugin::initPlugin at line 110 of /var/www/foswiki11/lib/Foswiki/Plugins/ExtendedWebListPlugin.pm # once (23µs+6µs) by Foswiki::Plugins::JHotDrawPlugin::initPlugin at line 37 of /var/www/foswiki11/lib/Foswiki/Plugins/JHotDrawPlugin.pm # once (22µs+7µs) by Foswiki::Plugins::HolidaylistPlugin::initPlugin at line 15 of /var/www/foswiki11/lib/Foswiki/Plugins/HolidaylistPlugin.pm # once (24µs+6µs) by Foswiki::Plugins::HistoryPlugin::initPlugin at line 28 of /var/www/foswiki11/lib/Foswiki/Plugins/HistoryPlugin.pm # once (24µs+4µs) by Foswiki::Plugins::WysiwygPlugin::initPlugin at line 57 of /var/www/foswiki11/lib/Foswiki/Plugins/WysiwygPlugin.pm # once (22µs+5µs) by Foswiki::Plugins::MultiTopicSavePlugin::initPlugin at line 103 of /var/www/foswiki11/lib/Foswiki/Plugins/MultiTopicSavePlugin.pm # once (21µs+6µs) by Foswiki::Plugins::RevisionLinkPlugin::initPlugin at line 94 of /var/www/foswiki11/lib/Foswiki/Plugins/RevisionLinkPlugin.pm # once (22µs+4µs) by Foswiki::Plugins::TimeCalcPlugin::initPlugin at line 118 of /var/www/foswiki11/lib/Foswiki/Plugins/TimeCalcPlugin.pm # once (21µs+5µs) by Foswiki::Plugins::AttachContentPlugin::initPlugin at line 56 of /var/www/foswiki11/lib/Foswiki/Plugins/AttachContentPlugin.pm # once (20µs+5µs) by Foswiki::Plugins::DelayMacroPlugin::initPlugin at line 87 of /var/www/foswiki11/lib/Foswiki/Plugins/DelayMacroPlugin.pm # once (18µs+6µs) by Foswiki::Plugins::ExpandTopicContentPlugin::initPlugin at line 104 of /var/www/foswiki11/lib/Foswiki/Plugins/ExpandTopicContentPlugin.pm # once (19µs+5µs) by Foswiki::Plugins::TwistyPlugin::initPlugin at line 49 of /var/www/foswiki11/lib/Foswiki/Plugins/TwistyPlugin.pm # once (19µs+5µs) by Foswiki::Plugins::JQueryPlugin::initPlugin at line 54 of /var/www/foswiki11/lib/Foswiki/Plugins/JQueryPlugin.pm # once (18µs+4µs) by Foswiki::Plugins::JQueryPlugin::initPlugin at line 39 of /var/www/foswiki11/lib/Foswiki/Plugins/JQueryPlugin.pm # once (17µs+5µs) by Foswiki::Plugins::JQueryPlugin::initPlugin at line 42 of /var/www/foswiki11/lib/Foswiki/Plugins/JQueryPlugin.pm # once (17µs+4µs) by Foswiki::Plugins::JQueryPlugin::initPlugin at line 40 of /var/www/foswiki11/lib/Foswiki/Plugins/JQueryPlugin.pm # once (17µs+5µs) by Foswiki::Plugins::JQueryPlugin::initPlugin at line 45 of /var/www/foswiki11/lib/Foswiki/Plugins/JQueryPlugin.pm # once (16µs+5µs) by Foswiki::Plugins::MultiTopicSavePlugin::initPlugin at line 107 of /var/www/foswiki11/lib/Foswiki/Plugins/MultiTopicSavePlugin.pm # once (17µs+5µs) by Foswiki::Plugins::MultiTopicSavePlugin::initPlugin at line 110 of /var/www/foswiki11/lib/Foswiki/Plugins/MultiTopicSavePlugin.pm # once (17µs+4µs) by Foswiki::Plugins::MultiTopicSavePlugin::initPlugin at line 114 of /var/www/foswiki11/lib/Foswiki/Plugins/MultiTopicSavePlugin.pm # once (16µs+5µs) by Foswiki::Plugins::JQueryPlugin::initPlugin at line 51 of /var/www/foswiki11/lib/Foswiki/Plugins/JQueryPlugin.pm # once (17µs+4µs) by Foswiki::Plugins::JQueryPlugin::initPlugin at line 48 of /var/www/foswiki11/lib/Foswiki/Plugins/JQueryPlugin.pm # once (16µs+4µs) by Foswiki::Plugins::JQueryPlugin::initPlugin at line 41 of /var/www/foswiki11/lib/Foswiki/Plugins/JQueryPlugin.pm # once (16µs+4µs) by Foswiki::Plugins::JQueryPlugin::initPlugin at line 46 of /var/www/foswiki11/lib/Foswiki/Plugins/JQueryPlugin.pm # once (16µs+4µs) by Foswiki::Plugins::WysiwygPlugin::initPlugin at line 59 of /var/www/foswiki11/lib/Foswiki/Plugins/WysiwygPlugin.pm # once (16µs+4µs) by Foswiki::Plugins::TimeCalcPlugin::initPlugin at line 119 of /var/www/foswiki11/lib/Foswiki/Plugins/TimeCalcPlugin.pm # once (15µs+5µs) by Foswiki::Plugins::WysiwygPlugin::initPlugin at line 63 of /var/www/foswiki11/lib/Foswiki/Plugins/WysiwygPlugin.pm # once (16µs+4µs) by Foswiki::Plugins::TimeCalcPlugin::initPlugin at line 120 of /var/www/foswiki11/lib/Foswiki/Plugins/TimeCalcPlugin.pm # once (16µs+4µs) by Foswiki::Plugins::JQueryPlugin::initPlugin at line 47 of /var/www/foswiki11/lib/Foswiki/Plugins/JQueryPlugin.pm # once (16µs+4µs) by Foswiki::Plugins::TwistyPlugin::initPlugin at line 51 of /var/www/foswiki11/lib/Foswiki/Plugins/TwistyPlugin.pm # once (15µs+3µs) by Foswiki::Plugins::WysiwygPlugin::initPlugin at line 61 of /var/www/foswiki11/lib/Foswiki/Plugins/WysiwygPlugin.pm # once (14µs+4µs) by Foswiki::Plugins::WysiwygPlugin::initPlugin at line 65 of /var/www/foswiki11/lib/Foswiki/Plugins/WysiwygPlugin.pm # once (14µs+4µs) by Foswiki::Plugins::TwistyPlugin::initPlugin at line 52 of /var/www/foswiki11/lib/Foswiki/Plugins/TwistyPlugin.pm # once (14µs+4µs) by Foswiki::Plugins::TwistyPlugin::initPlugin at line 50 of /var/www/foswiki11/lib/Foswiki/Plugins/TwistyPlugin.pm # once (15µs+3µs) by Foswiki::Plugins::TwistyPlugin::initPlugin at line 53 of /var/www/foswiki11/lib/Foswiki/Plugins/TwistyPlugin.pm # once (14µs+4µs) by Foswiki::Plugins::TimeCalcPlugin::initPlugin at line 121 of /var/www/foswiki11/lib/Foswiki/Plugins/TimeCalcPlugin.pm # once (14µs+4µs) by Foswiki::Plugins::TwistyPlugin::initPlugin at line 54 of /var/www/foswiki11/lib/Foswiki/Plugins/TwistyPlugin.pm # once (14µs+4µs) by Foswiki::Plugins::TwistyPlugin::initPlugin at line 55 of /var/www/foswiki11/lib/Foswiki/Plugins/TwistyPlugin.pm
sub registerTagHandler {
5764434µs my ( $tag, $function, $syntax ) = @_;
5774444µs4439µs ASSERT($Foswiki::Plugins::SESSION) if DEBUG;
# spent 39µs making 44 calls to Assert::ASSERTS_OFF, avg 880ns/call
5784450µs4433µs ASSERT( $Foswiki::Plugins::SESSION->isa('Foswiki') ) if DEBUG;
# spent 33µs making 44 calls to Assert::ASSERTS_OFF, avg 745ns/call
579
580 # $pluginContext is undefined if a contrib registers a tag handler.
581447µs my $pluginContext;
58244297µs if ( caller =~ m/^Foswiki::Plugins::(\w+)/ ) {
583 $pluginContext = $1 . 'Enabled';
584 }
585
586 # Use an anonymous function so it gets inlined at compile time.
587 # Make sure we don't mangle the session reference.
588 Foswiki::registerTagHandler(
589 $tag,
590
# spent 8.35s (112µs+8.35) within Foswiki::Func::__ANON__[/var/www/foswiki11/lib/Foswiki/Func.pm:611] which was called 4 times, avg 2.09s/call: # 4 times (112µs+8.35s) by Foswiki::_expandMacroOnTopicRendering at line 3160 of /var/www/foswiki11/lib/Foswiki.pm, avg 2.09s/call
sub {
59145µs my ( $session, $params, $topicObject ) = @_;
59242µs local $Foswiki::Plugins::SESSION = $session;
593
594 # $pluginContext is defined for all plugins
595 # but never defined for contribs.
596 # This is convenient, because contribs cannot be disabled
597 # at run-time, either.
598410µs412µs if ( defined $pluginContext ) {
# spent 12µs making 4 calls to Foswiki::inContext, avg 3µs/call
599
600 # Registered tag handlers should only be called if the plugin
601 # is enabled. Disabled plugins can still have tag handlers
602 # registered in persistent environments (e.g. modperl)
603 # and also for rest handlers that disable plugins.
604 # See Item1871
605 return unless $session->inContext($pluginContext);
606 }
607
608 # Compatibility; expand $topicObject to the topic and web
609458µs128.35s return &$function( $session, $params, $topicObject->topic,
# spent 8.35s making 1 call to Foswiki::Plugins::ExtendedWebListPlugin::_EXTENDEDWEBLIST # spent 858µs making 2 calls to Foswiki::Plugins::TimeCalcPlugin::_TIMESHOWSTORE, avg 429µs/call # spent 94µs making 1 call to Foswiki::Plugins::JQueryPlugin::handleJQueryTheme # spent 10µs making 4 calls to Foswiki::Meta::topic, avg 3µs/call # spent 9µs making 4 calls to Foswiki::Meta::web, avg 2µs/call
610 $topicObject->web, $topicObject );
611 },
61244345µs44162µs $syntax
# spent 162µs making 44 calls to Foswiki::registerTagHandler, avg 4µs/call
613 );
614}
615
616=begin TML=
617
618---+++ registerRESTHandler( $alias, \&fn, %options )
619
620Should only be called from initPlugin.
621
622Adds a function to the dispatch table of the REST interface
623 * =$alias= - The name .
624 * =\&fn= - Reference to the function.
625 * =%options= - additional options affecting the handler
626The handler function must be of the form:
627<verbatim>
628sub handler(\%session)
629</verbatim>
630where:
631 * =\%session= - a reference to the Foswiki session object (may be ignored)
632
633From the REST interface, the name of the plugin must be used
634as the subject of the invokation.
635
636Additional options are set in the =%options= hash. These options are important
637to ensuring that requests to your handler can't be used in cross-scripting
638attacks, or used for phishing.
639 * =authenticate= - use this boolean option to require authentication for the
640 handler. If this is set, then an authenticated session must be in place
641 or the REST call will be rejected with a 401 (Unauthorized) status code.
642 By default, rest handlers do *not* require authentication.
643 * =validate= - use this boolean option to require validation of any requests
644 made to this handler. Validation is the process by which a secret key
645 is passed to the server so it can identify the origin of the request.
646 By default, requests made to REST handlers are not validated.
647 * =http_allow= use this option to specify that the HTTP methods that can
648 be used to invoke the handler. For example, =http_allow=>'POST,GET'= will
649 constrain the handler to be invoked using POST and GET, but not other
650 HTTP methods, such as DELETE. Normally you will use http_allow=>'POST'.
651 Together with authentication this is an important security tool.
652 Handlers that can be invoked using GET are vulnerable to being called
653 in the =src= parameter of =img= tags, a common method for cross-site
654 request forgery (CSRF) attacks. This option is set automatically if
655 =authenticate= is specified.
656
657---++++ Example
658
659The EmptyPlugin has the following call in the initPlugin handler:
660<verbatim>
661 Foswiki::Func::registerRESTHandler('example', \&restExample,
662 http_allow=>'GET,POST');
663</verbatim>
664
665This adds the =restExample= function to the REST dispatch table
666for the EmptyPlugin under the 'example' alias, and allows it
667to be invoked using the URL
668
669=http://server:port/bin/rest/EmptyPlugin/example=
670
671note that the URL
672
673=http://server:port/bin/rest/EmptyPlugin/restExample=
674
675(ie, with the name of the function instead of the alias) will not work.
676
677---++++ Calling REST handlers from the command-line
678The =rest= script allows handlers to be invoked from the command line. The
679script is invoked passing the parameters as described in CommandAndCGIScripts.
680If the handler requires authentication ( =authenticate=>1= ) then this can
681be passed in the username and =password= parameters.
682
683For example,
684
685=perl -wT rest /EmptyPlugin/example -username HughPugh -password trumpton=
686
687=cut
688
689
# spent 3.10ms (2.50+600µs) within Foswiki::Func::registerRESTHandler which was called 13 times, avg 238µs/call: # once (2.28ms+520µs) by Foswiki::Plugins::ActionTrackerPlugin::initPlugin at line 29 of /var/www/foswiki11/lib/Foswiki/Plugins/ActionTrackerPlugin.pm # once (22µs+9µs) by Foswiki::Plugins::MultiTopicSavePlugin::initPlugin at line 124 of /var/www/foswiki11/lib/Foswiki/Plugins/MultiTopicSavePlugin.pm # once (22µs+8µs) by Foswiki::Plugins::RenderPlugin::initPlugin at line 42 of /var/www/foswiki11/lib/Foswiki/Plugins/RenderPlugin.pm # once (19µs+9µs) by Foswiki::Plugins::RenderPlugin::initPlugin at line 54 of /var/www/foswiki11/lib/Foswiki/Plugins/RenderPlugin.pm # once (21µs+7µs) by Foswiki::Plugins::MailerContribPlugin::initPlugin at line 14 of /var/www/foswiki11/lib/Foswiki/Plugins/MailerContribPlugin.pm # once (21µs+7µs) by Foswiki::Plugins::JHotDrawPlugin::initPlugin at line 39 of /var/www/foswiki11/lib/Foswiki/Plugins/JHotDrawPlugin.pm # once (16µs+9µs) by Foswiki::Plugins::RenderPlugin::initPlugin at line 60 of /var/www/foswiki11/lib/Foswiki/Plugins/RenderPlugin.pm # once (17µs+6µs) by Foswiki::Plugins::RenderPlugin::initPlugin at line 48 of /var/www/foswiki11/lib/Foswiki/Plugins/RenderPlugin.pm # once (17µs+5µs) by Foswiki::Plugins::JHotDrawPlugin::initPlugin at line 40 of /var/www/foswiki11/lib/Foswiki/Plugins/JHotDrawPlugin.pm # once (16µs+5µs) by Foswiki::Plugins::WysiwygPlugin::initPlugin at line 68 of /var/www/foswiki11/lib/Foswiki/Plugins/WysiwygPlugin.pm # once (15µs+6µs) by Foswiki::Plugins::WysiwygPlugin::initPlugin at line 74 of /var/www/foswiki11/lib/Foswiki/Plugins/WysiwygPlugin.pm # once (14µs+4µs) by Foswiki::Plugins::WysiwygPlugin::initPlugin at line 70 of /var/www/foswiki11/lib/Foswiki/Plugins/WysiwygPlugin.pm # once (13µs+4µs) by Foswiki::Plugins::WysiwygPlugin::initPlugin at line 72 of /var/www/foswiki11/lib/Foswiki/Plugins/WysiwygPlugin.pm
sub registerRESTHandler {
6901320µs my ( $alias, $function, %options ) = @_;
6911315µs1312µs ASSERT($Foswiki::Plugins::SESSION) if DEBUG;
# spent 12µs making 13 calls to Assert::ASSERTS_OFF, avg 946ns/call
6921347µs my $plugin = caller;
6931338µs $plugin =~ s/.*:://; # strip off Foswiki::Plugins:: prefix
694
695 # Use an anonymous function so it gets inlined at compile time.
696 # Make sure we don't mangle the session reference.
69713162µs require Foswiki::UI::Rest;
698 Foswiki::UI::Rest::registerRESTHandler(
699 $plugin, $alias,
700 sub {
701 my $record = $Foswiki::Plugins::SESSION;
702 $Foswiki::Plugins::SESSION = $_[0];
703 ASSERT( $Foswiki::Plugins::SESSION->isa('Foswiki') ) if DEBUG;
704 my $result = &$function(@_);
705 $Foswiki::Plugins::SESSION = $record;
706 return $result;
707 },
70813124µs1383µs %options
# spent 83µs making 13 calls to Foswiki::UI::Rest::registerRESTHandler, avg 6µs/call
709 );
710}
711
712=begin TML
713
714---+++ registerMETA($macro, $spec)
715Deprecated: please use Foswiki::Meta::registerMETA instead.
716
717=cut
718
719sub registerMETA {
720
721 #my ( $macro, %spec ) = @_;
722 Foswiki::Meta::registerMETA(@_);
723}
724
725=begin TML
726
727---++ Preferences
728
729=cut
730
731=begin TML
732
733---+++ getPreferencesValue( $key, $web ) -> $value
734
735Get a preferences value for the currently requested context, from the currently request topic, its web and the site.
736 * =$key= - Preference name
737 * =$web= - Name of web, optional. If defined, we shortcircuit to WebPreferences (ignoring SitePreferences). This is really only useful for ACLs.
738Return: =$value= Preferences value; empty string if not set
739
740 * Example for preferences setting:
741 * WebPreferences topic has: =* Set WEBBGCOLOR = #FFFFC0=
742 * =my $webColor = Foswiki::Func::getPreferencesValue( 'WEBBGCOLOR', 'Sandbox' );=
743
744 * Example for MyPlugin setting:
745 * if the %SYSTEMWEB%.MyPlugin topic has: =* Set COLOR = red=
746 * Use ="MYPLUGIN_COLOR"= for =$key=
747 * =my $color = Foswiki::Func::getPreferencesValue( "MYPLUGIN_COLOR" );=
748
749*NOTE:* If =$NO_PREFS_IN_TOPIC= is enabled in the plugin, then
750preferences set in the plugin topic will be ignored.
751
752=cut
753
754
# spent 2.07ms (430µs+1.64) within Foswiki::Func::getPreferencesValue which was called 50 times, avg 41µs/call: # 14 times (118µs+641µs) by Foswiki::Func::getPreferencesFlag at line 818, avg 54µs/call # 5 times (52µs+129µs) by Foswiki::Plugins::TablePlugin::preRenderingHandler at line 59 of /var/www/foswiki11/lib/Foswiki/Plugins/TablePlugin.pm, avg 36µs/call # once (8µs+54µs) by Foswiki::Plugins::JQueryPlugin::FOSWIKI::init at line 60 of /var/www/foswiki11/lib/Foswiki/Plugins/JQueryPlugin/FOSWIKI.pm # once (7µs+48µs) by Foswiki::Plugins::InterwikiPlugin::initPlugin at line 66 of /var/www/foswiki11/lib/Foswiki/Plugins/InterwikiPlugin.pm # once (8µs+46µs) by Foswiki::Plugins::JQueryPlugin::FOSWIKI::init at line 74 of /var/www/foswiki11/lib/Foswiki/Plugins/JQueryPlugin/FOSWIKI.pm # once (6µs+42µs) by Foswiki::Plugins::SmiliesPlugin::initPlugin at line 28 of /var/www/foswiki11/lib/Foswiki/Plugins/SmiliesPlugin.pm # once (6µs+40µs) by Foswiki::Plugins::TablePlugin::_readPluginSettings at line 127 of /var/www/foswiki11/lib/Foswiki/Plugins/TablePlugin.pm # once (12µs+34µs) by Foswiki::Contrib::JSCalendarContrib::addHEAD at line 198 of /var/www/foswiki11/lib/Foswiki/Contrib/JSCalendarContrib.pm # once (16µs+26µs) by Foswiki::Plugins::DirectedGraphPlugin::initPlugin at line 258 of /var/www/foswiki11/lib/Foswiki/Plugins/DirectedGraphPlugin.pm # once (16µs+25µs) by Foswiki::Plugins::FindElsewherePlugin::Core::_lazyInit at line 50 of /var/www/foswiki11/lib/Foswiki/Plugins/FindElsewherePlugin/Core.pm # once (10µs+31µs) by Foswiki::Plugins::AutoViewTemplatePlugin::initPlugin at line 45 of /var/www/foswiki11/lib/Foswiki/Plugins/AutoViewTemplatePlugin.pm # once (8µs+27µs) by Foswiki::Plugins::InterwikiPlugin::initPlugin at line 62 of /var/www/foswiki11/lib/Foswiki/Plugins/InterwikiPlugin.pm # once (8µs+27µs) by Foswiki::Plugins::DirectedGraphPlugin::initPlugin at line 238 of /var/www/foswiki11/lib/Foswiki/Plugins/DirectedGraphPlugin.pm # once (8µs+26µs) by Foswiki::Contrib::JSCalendarContrib::addHEAD at line 202 of /var/www/foswiki11/lib/Foswiki/Contrib/JSCalendarContrib.pm # once (8µs+26µs) by Foswiki::Plugins::SpreadSheetPlugin::initPlugin at line 55 of /var/www/foswiki11/lib/Foswiki/Plugins/SpreadSheetPlugin.pm # once (9µs+24µs) by Foswiki::Plugins::DirectedGraphPlugin::initPlugin at line 282 of /var/www/foswiki11/lib/Foswiki/Plugins/DirectedGraphPlugin.pm # once (9µs+24µs) by Foswiki::Plugins::DirectedGraphPlugin::initPlugin at line 277 of /var/www/foswiki11/lib/Foswiki/Plugins/DirectedGraphPlugin.pm # once (8µs+25µs) by Foswiki::Plugins::DirectedGraphPlugin::initPlugin at line 253 of /var/www/foswiki11/lib/Foswiki/Plugins/DirectedGraphPlugin.pm # once (8µs+24µs) by Foswiki::Plugins::DirectedGraphPlugin::initPlugin at line 302 of /var/www/foswiki11/lib/Foswiki/Plugins/DirectedGraphPlugin.pm # once (8µs+24µs) by Foswiki::Plugins::DirectedGraphPlugin::initPlugin at line 272 of /var/www/foswiki11/lib/Foswiki/Plugins/DirectedGraphPlugin.pm # once (8µs+24µs) by Foswiki::Plugins::DirectedGraphPlugin::initPlugin at line 243 of /var/www/foswiki11/lib/Foswiki/Plugins/DirectedGraphPlugin.pm # once (8µs+24µs) by Foswiki::Plugins::DirectedGraphPlugin::initPlugin at line 262 of /var/www/foswiki11/lib/Foswiki/Plugins/DirectedGraphPlugin.pm # once (8µs+24µs) by Foswiki::Plugins::PlantUMLPlugin::initPlugin at line 152 of /var/www/foswiki11/lib/Foswiki/Plugins/PlantUMLPlugin.pm # once (8µs+24µs) by Foswiki::Plugins::DirectedGraphPlugin::initPlugin at line 297 of /var/www/foswiki11/lib/Foswiki/Plugins/DirectedGraphPlugin.pm # once (8µs+23µs) by Foswiki::Plugins::TwistyPlugin::_exportAnimationSpeed at line 62 of /var/www/foswiki11/lib/Foswiki/Plugins/TwistyPlugin.pm # once (7µs+24µs) by Foswiki::Plugins::DirectedGraphPlugin::initPlugin at line 248 of /var/www/foswiki11/lib/Foswiki/Plugins/DirectedGraphPlugin.pm # once (7µs+24µs) by Foswiki::Plugins::DirectedGraphPlugin::initPlugin at line 267 of /var/www/foswiki11/lib/Foswiki/Plugins/DirectedGraphPlugin.pm # once (7µs+24µs) by Foswiki::Plugins::DirectedGraphPlugin::initPlugin at line 287 of /var/www/foswiki11/lib/Foswiki/Plugins/DirectedGraphPlugin.pm # once (8µs+24µs) by Foswiki::Plugins::SmiliesPlugin::initPlugin at line 25 of /var/www/foswiki11/lib/Foswiki/Plugins/SmiliesPlugin.pm # once (7µs+23µs) by Foswiki::Plugins::DirectedGraphPlugin::initPlugin at line 292 of /var/www/foswiki11/lib/Foswiki/Plugins/DirectedGraphPlugin.pm # once (7µs+21µs) by Foswiki::Plugins::TablePlugin::Core::handler at line 1886 of /var/www/foswiki11/lib/Foswiki/Plugins/TablePlugin/Core.pm # once (7µs+20µs) by Foswiki::Plugins::PlantUMLPlugin::initPlugin at line 157 of /var/www/foswiki11/lib/Foswiki/Plugins/PlantUMLPlugin.pm # once (7µs+18µs) by Foswiki::Plugins::FindElsewherePlugin::Core::_lazyInit at line 63 of /var/www/foswiki11/lib/Foswiki/Plugins/FindElsewherePlugin/Core.pm
sub getPreferencesValue {
7555035µs my ( $key, $web ) = @_;
7565057µs5050µs ASSERT($Foswiki::Plugins::SESSION) if DEBUG;
# spent 50µs making 50 calls to Assert::ASSERTS_OFF, avg 1µs/call
7575018µs if ($web) {
758 $web = _checkWTA($web);
759 return undef unless defined $web;
760
761 # Web preference
762 my $webObject = Foswiki::Meta->new( $Foswiki::Plugins::SESSION, $web );
763 return $webObject->getPreference($key);
764 }
765 else {
766
767 # Global preference
76850278µs501.59ms return $Foswiki::Plugins::SESSION->{prefs}->getPreference($key);
# spent 1.59ms making 50 calls to Foswiki::Prefs::getPreference, avg 32µs/call
769 }
770}
771
772=begin TML
773
774---+++ getPluginPreferencesValue( $key ) -> $value
775
776Get a preferences value from your Plugin
777 * =$key= - Plugin Preferences key w/o PLUGINNAME_ prefix.
778Return: =$value= Preferences value; empty string if not set
779
780__Note__: This function will will *only* work when called from the Plugin.pm file itself. it *will not work* if called from a sub-package (e.g. Foswiki::Plugins::MyPlugin::MyModule)
781
782*NOTE:* If =$NO_PREFS_IN_TOPIC= is enabled in the plugin, then
783preferences set in the plugin topic will be ignored.
784
785=cut
786
787
# spent 7.39ms (7.27+115µs) within Foswiki::Func::getPluginPreferencesValue which was called 3 times, avg 2.46ms/call: # once (7.23ms+27µs) by Foswiki::Plugins::FindElsewherePlugin::Core::_lazyInit at line 51 of /var/www/foswiki11/lib/Foswiki/Plugins/FindElsewherePlugin/Core.pm # once (23µs+47µs) by Foswiki::Plugins::RevCommentPlugin::initPlugin at line 65 of /var/www/foswiki11/lib/Foswiki/Plugins/RevCommentPlugin.pm # once (14µs+42µs) by Foswiki::Plugins::TwistyPlugin::_exportAnimationSpeed at line 62 of /var/www/foswiki11/lib/Foswiki/Plugins/TwistyPlugin.pm
sub getPluginPreferencesValue {
78833µs my ($key) = @_;
78934µs33µs ASSERT($Foswiki::Plugins::SESSION) if DEBUG;
# spent 3µs making 3 calls to Assert::ASSERTS_OFF, avg 867ns/call
790314µs my $package = caller;
791316µs $package =~ s/.*:://; # strip off Foswiki::Plugins:: prefix
792324µs3112µs return $Foswiki::Plugins::SESSION->{prefs}
# spent 112µs making 3 calls to Foswiki::Prefs::getPreference, avg 38µs/call
793 ->getPreference("\U$package\E_$key");
794}
795
796=begin TML
797
798---+++ getPreferencesFlag( $key, $web ) -> $value
799
800Get a preferences flag from Foswiki or from a Plugin
801 * =$key= - Preferences key
802 * =$web= - Name of web, optional. Current web if not specified; does not apply to settings of Plugin topics
803Return: =$value= Preferences flag ='1'= (if set), or ="0"= (for preferences values ="off"=, ="no"= and ="0"=)
804
805 * Example for Plugin setting:
806 * MyPlugin topic has: =* Set SHOWHELP = off=
807 * Use ="MYPLUGIN_SHOWHELP"= for =$key=
808 * =my $showHelp = Foswiki::Func::getPreferencesFlag( "MYPLUGIN_SHOWHELP" );=
809
810*NOTE:* If =$NO_PREFS_IN_TOPIC= is enabled in the plugin, then
811preferences set in the plugin topic will be ignored.
812
813=cut
814
815
# spent 971µs (117+855) within Foswiki::Func::getPreferencesFlag which was called 14 times, avg 69µs/call: # 2 times (14µs+177µs) by Foswiki::Func::getPluginPreferencesFlag at line 841, avg 96µs/call # once (8µs+143µs) by Foswiki::Plugins::ChartPlugin::initPlugin at line 70 of /var/www/foswiki11/lib/Foswiki/Plugins/ChartPlugin.pm # once (8µs+86µs) by Foswiki::Plugins::DirectedGraphPlugin::initPlugin at line 234 of /var/www/foswiki11/lib/Foswiki/Plugins/DirectedGraphPlugin.pm # once (6µs+75µs) by Foswiki::Plugins::RevisionLinkPlugin::initPlugin at line 92 of /var/www/foswiki11/lib/Foswiki/Plugins/RevisionLinkPlugin.pm # once (20µs+60µs) by Foswiki::Plugins::SpreadSheetPlugin::initPlugin at line 35 of /var/www/foswiki11/lib/Foswiki/Plugins/SpreadSheetPlugin.pm # once (5µs+67µs) by Foswiki::Plugins::FindElsewherePlugin::Core::_lazyInit at line 82 of /var/www/foswiki11/lib/Foswiki/Plugins/FindElsewherePlugin/Core.pm # once (17µs+46µs) by Foswiki::Plugins::EditTablePlugin::initPlugin at line 53 of /var/www/foswiki11/lib/Foswiki/Plugins/EditTablePlugin.pm # once (7µs+42µs) by Foswiki::Plugins::EditTablePlugin::initPlugin at line 52 of /var/www/foswiki11/lib/Foswiki/Plugins/EditTablePlugin.pm # once (6µs+38µs) by Foswiki::Plugins::FindElsewherePlugin::initPlugin at line 43 of /var/www/foswiki11/lib/Foswiki/Plugins/FindElsewherePlugin.pm # once (6µs+37µs) by Foswiki::Plugins::SpreadSheetPlugin::initPlugin at line 53 of /var/www/foswiki11/lib/Foswiki/Plugins/SpreadSheetPlugin.pm # once (6µs+35µs) by Foswiki::Plugins::PlantUMLPlugin::initPlugin at line 80 of /var/www/foswiki11/lib/Foswiki/Plugins/PlantUMLPlugin.pm # once (7µs+25µs) by Foswiki::Plugins::FindElsewherePlugin::Core::_lazyInit at line 65 of /var/www/foswiki11/lib/Foswiki/Plugins/FindElsewherePlugin/Core.pm # once (4µs+24µs) by Foswiki::Plugins::FindElsewherePlugin::Core::_lazyInit at line 74 of /var/www/foswiki11/lib/Foswiki/Plugins/FindElsewherePlugin/Core.pm
sub getPreferencesFlag {
816
817 # my( $key, $web ) = @_;
8181435µs14759µs my $t = getPreferencesValue(@_);
# spent 759µs making 14 calls to Foswiki::Func::getPreferencesValue, avg 54µs/call
8191486µs1495µs return Foswiki::isTrue($t);
# spent 95µs making 14 calls to Foswiki::isTrue, avg 7µs/call
820}
821
822=begin TML
823
824---+++ getPluginPreferencesFlag( $key ) -> $boolean
825
826Get a preferences flag from your Plugin
827 * =$key= - Plugin Preferences key w/o PLUGINNAME_ prefix.
828Return: false for preferences values ="off"=, ="no"= and ="0"=, or values not set at all. True otherwise.
829
830__Note__: This function will will *only* work when called from the Plugin.pm file itself. it *will not work* if called from a sub-package (e.g. Foswiki::Plugins::MyPlugin::MyModule)
831
832*NOTE:* If =$NO_PREFS_IN_TOPIC= is enabled in the plugin, then
833preferences set in the plugin topic will be ignored.
834
835=cut
836
837
# spent 229µs (38+191) within Foswiki::Func::getPluginPreferencesFlag which was called 2 times, avg 114µs/call: # once (24µs+104µs) by Foswiki::Plugins::ChecklistPlugin::initPlugin at line 87 of /var/www/foswiki11/lib/Foswiki/Plugins/ChecklistPlugin.pm # once (14µs+87µs) by Foswiki::Plugins::RevCommentPlugin::initPlugin at line 62 of /var/www/foswiki11/lib/Foswiki/Plugins/RevCommentPlugin.pm
sub getPluginPreferencesFlag {
83822µs my ($key) = @_;
839210µs my $package = caller;
84029µs $package =~ s/.*:://; # strip off Foswiki::Plugins:: prefix
841217µs2191µs return getPreferencesFlag("\U$package\E_$key");
# spent 191µs making 2 calls to Foswiki::Func::getPreferencesFlag, avg 96µs/call
842}
843
844=begin TML
845
846---+++ setPreferencesValue($name, $val)
847
848Set the preferences value so that future calls to getPreferencesValue will
849return this value, and =%$name%= will expand to the preference when used in
850future variable expansions.
851
852The preference only persists for the rest of this request. Finalised
853preferences cannot be redefined using this function.
854
855=cut
856
857sub setPreferencesValue {
858 my ( $name, $value ) = @_;
859 return $Foswiki::Plugins::SESSION->{prefs}
860 ->setSessionPreferences( $name => $value );
861}
862
863=begin TML
864
865---++ User Handling and Access Control
866---+++ getDefaultUserName( ) -> $loginName
867Get default user name as defined in the configuration as =DefaultUserLogin=
868
869Return: =$loginName= Default user name, e.g. ='guest'=
870
871=cut
872
873sub getDefaultUserName {
874 return $Foswiki::cfg{DefaultUserLogin};
875}
876
877=begin TML
878
879---+++ getCanonicalUserID( $user ) -> $cUID
880 * =$user= can be a login, wikiname or web.wikiname
881Return the cUID of the specified user. A cUID is a unique identifier which
882is assigned by Foswiki for each user.
883BEWARE: While the default TopicUserMapping uses a cUID that looks like a user's
884LoginName, some characters are modified to make them compatible with rcs.
885Other usermappings may use other conventions - the !JoomlaUserMapping
886for example, has cUIDs like 'JoomlaeUserMapping_1234'.
887
888If $user is undefined, it assumes the currently logged-in user.
889
890Return: =$cUID=, an internal unique and portable escaped identifier for
891registered users. This may be autogenerated for an authenticated but
892unregistered user.
893
894=cut
895
896
# spent 28µs (17+11) within Foswiki::Func::getCanonicalUserID which was called: # once (17µs+11µs) by Foswiki::Func::checkAccessPermission at line 1413
sub getCanonicalUserID {
8971900ns my $user = shift;
8981300ns return $Foswiki::Plugins::SESSION->{user} unless ($user);
89911µs1700ns ASSERT($Foswiki::Plugins::SESSION) if DEBUG;
# spent 700ns making 1 call to Assert::ASSERTS_OFF
9001500ns my $cUID;
9011800ns if ($user) {
90214µs110µs $cUID = $Foswiki::Plugins::SESSION->{users}->getCanonicalUserID($user);
# spent 10µs making 1 call to Foswiki::Users::getCanonicalUserID
9031300ns if ( !$cUID ) {
904
905 # Not a login name or a wiki name. Is it a valid cUID?
906 my $ln = $Foswiki::Plugins::SESSION->{users}->getLoginName($user);
907 $cUID = $user if defined $ln && $ln ne 'unknown';
908 }
909 }
910 else {
911 $cUID = $Foswiki::Plugins::SESSION->{user};
912 }
91315µs return $cUID;
914}
915
916=begin TML
917
918---+++ getWikiName( $user ) -> $wikiName
919
920return the WikiName of the specified user
921if $user is undefined Get Wiki name of logged in user
922
923 * $user can be a cUID, login, wikiname or web.wikiname
924
925Return: =$wikiName= Wiki Name, e.g. ='JohnDoe'=
926
927=cut
928
929sub getWikiName {
930 my $user = shift;
931 ASSERT($Foswiki::Plugins::SESSION) if DEBUG;
932 my $cUID = getCanonicalUserID($user);
933 unless ( defined $cUID ) {
934 my ( $w, $u ) =
935 normalizeWebTopicName( $Foswiki::cfg{UsersWebName}, $user );
936 return $u;
937 }
938 return $Foswiki::Plugins::SESSION->{users}->getWikiName($cUID);
939}
940
941=begin TML
942
943---+++ getWikiUserName( $user ) -> $wikiName
944
945return the userWeb.WikiName of the specified user
946if $user is undefined Get Wiki name of logged in user
947
948 * $user can be a cUID, login, wikiname or web.wikiname
949
950Return: =$wikiName= Wiki Name, e.g. ="Main.JohnDoe"=
951
952=cut
953
954sub getWikiUserName {
955 my $user = shift;
956 ASSERT($Foswiki::Plugins::SESSION) if DEBUG;
957 my $cUID = getCanonicalUserID($user);
958 unless ( defined $cUID ) {
959 my ( $w, $u ) =
960 normalizeWebTopicName( $Foswiki::cfg{UsersWebName}, $user );
961 return "$w.$u";
962 }
963 return $Foswiki::Plugins::SESSION->{users}->webDotWikiName($cUID);
964}
965
966=begin TML
967
968---+++ wikiToUserName( $id ) -> $loginName
969Translate a Wiki name to a login name.
970 * =$id= - Wiki name, e.g. ='Main.JohnDoe'= or ='JohnDoe'=.
971 $id may also be a login name. This will normally
972 be transparent, but should be borne in mind if you have login names
973 that are also legal wiki names.
974
975Return: =$loginName= Login name of user, e.g. ='jdoe'=, or undef if not
976matched.
977
978Note that it is possible for several login names to map to the same wikiname.
979This function will only return the *first* login name that maps to the
980wikiname.
981
982returns undef if the WikiName is not found.
983
984=cut
985
986sub wikiToUserName {
987 my ($wiki) = @_;
988 ASSERT($Foswiki::Plugins::SESSION) if DEBUG;
989 return '' unless $wiki;
990
991 my $cUID = getCanonicalUserID($wiki);
992 if ($cUID) {
993 my $login = $Foswiki::Plugins::SESSION->{users}->getLoginName($cUID);
994 return if !$login || $login eq 'unknown';
995 return $login;
996 }
997 return;
998}
999
1000=begin TML
1001
1002---+++ userToWikiName( $loginName, $dontAddWeb ) -> $wikiName
1003Translate a login name to a Wiki name
1004 * =$loginName= - Login name, e.g. ='jdoe'=. This may
1005 also be a wiki name. This will normally be transparent, but may be
1006 relevant if you have login names that are also valid wiki names.
1007 * =$dontAddWeb= - Do not add web prefix if ="1"=
1008Return: =$wikiName= Wiki name of user, e.g. ='Main.JohnDoe'= or ='JohnDoe'=
1009
1010userToWikiName will always return a name. If the user does not
1011exist in the mapping, the $loginName parameter is returned. (backward compatibility)
1012
1013=cut
1014
1015sub userToWikiName {
1016 my ( $login, $dontAddWeb ) = @_;
1017 return '' unless $login;
1018 ASSERT($Foswiki::Plugins::SESSION) if DEBUG;
1019 my $users = $Foswiki::Plugins::SESSION->{users};
1020 my $user = getCanonicalUserID($login);
1021 return (
1022 $dontAddWeb
1023 ? $login
1024 : ( $Foswiki::cfg{UsersWebName} . '.' . $login )
1025 ) unless $user and $users->userExists($user);
1026 return $users->getWikiName($user) if $dontAddWeb;
1027 return $users->webDotWikiName($user);
1028}
1029
1030=begin TML
1031
1032---+++ emailToWikiNames( $email, $dontAddWeb ) -> @wikiNames
1033 * =$email= - email address to look up
1034 * =$dontAddWeb= - Do not add web prefix if ="1"=
1035Find the wikinames of all users who have the given email address as their
1036registered address. Since several users could register with the same email
1037address, this returns a list of wikinames rather than a single wikiname.
1038
1039=cut
1040
1041sub emailToWikiNames {
1042 my ( $email, $dontAddWeb ) = @_;
1043 ASSERT($email) if DEBUG;
1044
1045 my %matches;
1046 my $users = $Foswiki::Plugins::SESSION->{users};
1047 my $ua = $users->findUserByEmail($email);
1048 if ($ua) {
1049 foreach my $user (@$ua) {
1050 if ($dontAddWeb) {
1051 $matches{ $users->getWikiName($user) } = 1;
1052 }
1053 else {
1054 $matches{ $users->webDotWikiName($user) } = 1;
1055 }
1056 }
1057 }
1058
1059 return sort keys %matches;
1060}
1061
1062=begin TML
1063
1064---+++ wikinameToEmails( $user ) -> @emails
1065 * =$user= - wikiname of user to look up
1066Returns the registered email addresses of the named user. If $user is
1067undef, returns the registered email addresses for the logged-in user.
1068
1069$user may also be a group.
1070
1071=cut
1072
1073sub wikinameToEmails {
1074 my ($wikiname) = @_;
1075 if ($wikiname) {
1076 if ( isGroup($wikiname) ) {
1077 return $Foswiki::Plugins::SESSION->{users}->getEmails($wikiname);
1078 }
1079 else {
1080 my $uids =
1081 $Foswiki::Plugins::SESSION->{users}
1082 ->findUserByWikiName($wikiname);
1083 my @em = ();
1084 foreach my $user (@$uids) {
1085 push( @em,
1086 $Foswiki::Plugins::SESSION->{users}->getEmails($user) );
1087 }
1088 return @em;
1089 }
1090 }
1091 else {
1092 my $user = $Foswiki::Plugins::SESSION->{user};
1093 return $Foswiki::Plugins::SESSION->{users}->getEmails($user);
1094 }
1095}
1096
1097=begin TML
1098
1099---+++ isGuest( ) -> $boolean
1100
1101Test if logged in user is a guest (WikiGuest)
1102
1103=cut
1104
1105sub isGuest {
1106 ASSERT($Foswiki::Plugins::SESSION) if DEBUG;
1107 return $Foswiki::Plugins::SESSION->{user} eq
1108 $Foswiki::Plugins::SESSION->{users}
1109 ->getCanonicalUserID( $Foswiki::cfg{DefaultUserLogin} );
1110}
1111
1112=begin TML
1113
1114---+++ isAnAdmin( $id ) -> $boolean
1115
1116Find out if the user is an admin or not. If the user is not given,
1117the currently logged-in user is assumed.
1118 * $id can be either a login name or a WikiName
1119
1120=cut
1121
1122sub isAnAdmin {
1123 my $user = shift;
1124 return $Foswiki::Plugins::SESSION->{users}
1125 ->isAdmin( getCanonicalUserID($user) );
1126}
1127
1128=begin TML
1129
1130---+++ isGroupMember( $group, $id, $options ) -> $boolean
1131
1132Find out if $id is in the named group. The expand option controls whether or not nested groups are searched.
1133
1134e.g. Is jordi in the HesperionXXGroup, and not in a nested group. e.g.
1135<verbatim>
1136if( Foswiki::Func::isGroupMember( "HesperionXXGroup", "jordi", { expand => 0 } )) {
1137 ...
1138}
1139</verbatim>
1140If =$user= is =undef=, it defaults to the currently logged-in user.
1141
1142 * $id can be a login name or a WikiName
1143 * Nested groups are expanded unless $options{ expand => } is set to false.
1144
1145=cut
1146
1147sub isGroupMember {
1148 my ( $group, $user, $options ) = @_;
1149 my $users = $Foswiki::Plugins::SESSION->{users};
1150
1151 my $expand = Foswiki::Func::isTrue( $options->{expand}, 1 );
1152
1153 return () unless $users->isGroup($group);
1154 if ($user) {
1155
1156 #my $login = wikiToUserName( $user );
1157 #return 0 unless $login;
1158 $user = getCanonicalUserID($user) || $user;
1159 }
1160 else {
1161 $user = $Foswiki::Plugins::SESSION->{user};
1162 }
1163 return $users->isInGroup( $user, $group, { expand => $expand } );
1164}
1165
1166=begin TML
1167
1168---+++ eachUser() -> $iterator
1169Get an iterator over the list of all the registered users *not* including
1170groups. The iterator will return each wiki name in turn (e.g. 'FredBloggs').
1171
1172Use it as follows:
1173<verbatim>
1174 my $it = Foswiki::Func::eachUser();
1175 while ($it->hasNext()) {
1176 my $user = $it->next();
1177 # $user is a wikiname
1178 }
1179</verbatim>
1180
1181*WARNING* on large sites, this could be a long list!
1182
1183=cut
1184
1185sub eachUser {
1186 my $it = $Foswiki::Plugins::SESSION->{users}->eachUser();
1187 $it->{process} = sub {
1188 return $Foswiki::Plugins::SESSION->{users}->getWikiName( $_[0] );
1189 };
1190 return $it;
1191}
1192
1193=begin TML
1194
1195---+++ eachMembership($id) -> $iterator
1196 * =$id= - WikiName or login name of the user.
1197 If =$id= is =undef=, defaults to the currently logged-in user.
1198Get an iterator over the names of all groups that the user is a member of.
1199
1200=cut
1201
1202sub eachMembership {
1203 my ($user) = @_;
1204 my $users = $Foswiki::Plugins::SESSION->{users};
1205
1206 if ($user) {
1207 my $login = wikiToUserName($user);
1208 return 0 unless $login;
1209 $user = getCanonicalUserID($login);
1210 }
1211 else {
1212 $user = $Foswiki::Plugins::SESSION->{user};
1213 }
1214
1215 return $users->eachMembership($user);
1216}
1217
1218=begin TML
1219
1220---+++ eachGroup() -> $iterator
1221Get an iterator over all groups.
1222
1223Use it as follows:
1224<verbatim>
1225 my $iterator = Foswiki::Func::eachGroup();
1226 while ($it->hasNext()) {
1227 my $group = $it->next();
1228 # $group is a group name e.g. AdminGroup
1229 }
1230</verbatim>
1231
1232*WARNING* on large sites, this could be a long list!
1233
1234=cut
1235
1236sub eachGroup {
1237 my $session = $Foswiki::Plugins::SESSION;
1238 my $it = $session->{users}->eachGroup();
1239 return $it;
1240}
1241
1242=begin TML
1243
1244---+++ isGroup( $group ) -> $boolean
1245
1246Checks if =$group= is the name of a user group.
1247
1248=cut
1249
1250sub isGroup {
1251 my ($group) = @_;
1252
1253 return $Foswiki::Plugins::SESSION->{users}->isGroup($group);
1254}
1255
1256=begin TML
1257
1258---+++ eachGroupMember($group) -> $iterator
1259Get an iterator over all the members of the named group. Returns undef if
1260$group is not a valid group. Nested groups are expanded unless the
1261expand option is set to false.
1262
1263Use it as follows: Process all users in RadioHeadGroup without expanding nested groups
1264<verbatim>
1265 my $iterator = Foswiki::Func::eachGroupMember('RadioheadGroup', {expand => 'false');
1266 while ($it->hasNext()) {
1267 my $user = $it->next();
1268 # $user is a wiki name e.g. 'TomYorke', 'PhilSelway'
1269 # With expand set to false, group names can also be returned.
1270 # Users are not checked to exist.
1271 }
1272</verbatim>
1273
1274*WARNING* on large sites, this could be a long list!
1275
1276=cut
1277
1278sub eachGroupMember {
1279 my ( $user, $options ) = @_;
1280
1281 my $expand = Foswiki::Func::isTrue( $options->{expand}, 1 );
1282
1283 my $session = $Foswiki::Plugins::SESSION;
1284 return
1285 unless $Foswiki::Plugins::SESSION->{users}->isGroup($user);
1286 my $it =
1287 $Foswiki::Plugins::SESSION->{users}
1288 ->eachGroupMember( $user, { expand => $expand } );
1289 $it->{process} = sub {
1290 return $Foswiki::Plugins::SESSION->{users}->getWikiName( $_[0] );
1291 };
1292 return $it;
1293}
1294
1295=begin TML
1296
1297---+++ addUserToGroup( $id, $group, $create ) -> $boolean
1298
1299 * $id can be a login name or a WikiName
1300
1301=cut
1302
1303sub addUserToGroup {
1304 my ( $user, $group, $create ) = @_;
1305 my $users = $Foswiki::Plugins::SESSION->{users};
1306
1307 return () unless ( $users->isGroup($group) || $create );
1308 if ( defined $user && !$users->isGroup($user) )
1309 { #requires isInGroup to also work on nested groupnames
1310 $user = getCanonicalUserID($user) || $user;
1311 return unless ( defined($user) );
1312 }
1313 return $users->addUserToGroup( $user, $group, $create );
1314}
1315
1316=begin TML
1317
1318---+++ removeUserFromGroup( $group, $id ) -> $boolean
1319
1320 * $id can be a login name or a WikiName
1321
1322=cut
1323
1324sub removeUserFromGroup {
1325 my ( $user, $group ) = @_;
1326 my $users = $Foswiki::Plugins::SESSION->{users};
1327
1328 return () unless $users->isGroup($group);
1329
1330 if ( !$users->isGroup($user) )
1331 { #requires isInGroup to also work on nested groupnames
1332 $user = getCanonicalUserID($user) || $user;
1333 return unless ( defined($user) );
1334 }
1335 return $users->removeUserFromGroup( $user, $group );
1336}
1337
1338=begin TML
1339
1340---+++ checkAccessPermission( $type, $id, $text, $topic, $web, $meta ) -> $boolean
1341
1342Check access permission for a topic based on the
1343[[%SYSTEMWEB%.AccessControl]] rules
1344 * =$type= - Access type, required, e.g. ='VIEW'=, ='CHANGE'=.
1345 * =$id= - WikiName of remote user, required, e.g. ="RickShaw"=.
1346 $id may also be a login name.
1347 If =$id= is '', 0 or =undef= then access is *always permitted*. This is used
1348 by other functions if the caller should be able to bypass access checks.
1349 * =$text= - Topic text, optional. If 'perl false' (undef, 0 or ''),
1350 topic =$web.$topic= is consulted. =$text= may optionally contain embedded
1351 =%META:PREFERENCE= tags. Provide this parameter if:
1352 1 You are setting different access controls in the text to those defined
1353 in the stored topic,
1354 1 You already have the topic text in hand, and want to help avoid
1355 having to read it again,
1356 1 You are providing a =$meta= parameter.
1357 * =$topic= - Topic name, optional, e.g. ='PrivateStuff'=, '' or =undef=
1358 * If undefined, the Web preferences are checked.
1359 * If null, the default (WebHome) topic is checked.
1360 * If topic specified but does not exist, the web preferences are checked,
1361 allowing the caller to determine
1362 _"If the topic existed, would the operation be permitted"._
1363 * =$web= - Web name, required, e.g. ='Sandbox'=
1364 * If missing, the default Users Web (Main) is used.
1365 * =$meta= - Meta-data object, as returned by =readTopic=. Optional.
1366 If =undef=, but =$text= is defined, then access controls will be parsed
1367 from =$text=. If defined, then metadata embedded in =$text= will be
1368 ignored. This parameter is always ignored if =$text= is undefined.
1369 Settings in =$meta= override =Set= settings in $text.
1370A perl true result indicates that access is permitted.
1371
1372*Note* the weird parameter order is due to compatibility constraints with
1373earlier releases.
1374
1375<blockquote class="foswikiHelp">
1376%T% *Tip:* if you want, you can use this method to check your own access control types. For example, if you:
1377 * Set ALLOWTOPICSPIN = IncyWincy
1378in =ThatWeb.ThisTopic=, then a call to =checkAccessPermission('SPIN', 'IncyWincy', undef, 'ThisTopic', 'ThatWeb', undef)= will return =true=.
1379</blockquote>
1380
1381*Example code:*
1382
1383<verbatim>
1384 use Error qw(:try);
1385 use Foswiki::AccessControlException;
1386 ...
1387 unless (
1388 Foswiki::Func::checkAccessPermission(
1389 "VIEW", $session->{user}, undef, $topic, $web
1390 )
1391 )
1392 {
1393 throw Foswiki::AccessControlException( "VIEW", $session->{user}, $web,
1394 $topic, $Foswiki::Meta::reason );
1395 }
1396</verbatim>
1397
1398=cut
1399
1400
# spent 1.07ms (39µs+1.04) within Foswiki::Func::checkAccessPermission which was called: # once (39µs+1.04ms) by Foswiki::Plugins::InterwikiPlugin::initPlugin at line 76 of /var/www/foswiki11/lib/Foswiki/Plugins/InterwikiPlugin.pm
sub checkAccessPermission {
140112µs my ( $type, $user, $text, $inTopic, $inWeb, $meta ) = @_;
14021700ns return 1 unless ($user);
1403
140412µs130µs my ( $web, $topic ) = _checkWTA( $inWeb, $inTopic );
# spent 30µs making 1 call to Foswiki::Func::_checkWTA
14051400ns return 0 unless defined $web; #Web name is illegal.
14061700ns if ( defined $inTopic ) {
14071400ns my $top = $topic;
14081300ns return 0 unless ( defined $topic ); #Topic name is illegal
1409 }
1410
141112µs11µs ASSERT($Foswiki::Plugins::SESSION) if DEBUG;
# spent 1µs making 1 call to Assert::ASSERTS_OFF
14121400ns $text = undef unless $text;
141315µs128µs my $cUID = getCanonicalUserID($user)
# spent 28µs making 1 call to Foswiki::Func::getCanonicalUserID
1414 || getCanonicalUserID( $Foswiki::cfg{DefaultUserLogin} );
141511µs if ( !defined($meta) ) {
14161900ns if ($text) {
1417 $meta = Foswiki::Meta->new( $Foswiki::Plugins::SESSION,
1418 $web, $topic, $text );
1419 }
1420 else {
142114µs1612µs $meta =
# spent 612µs making 1 call to Foswiki::Meta::load
1422 Foswiki::Meta->load( $Foswiki::Plugins::SESSION, $web, $topic );
1423 }
1424 }
1425 elsif ($text) {
1426
1427 # don't alter an existing $meta using the provided text;
1428 # use a temporary clone instead
1429 my $tmpMeta =
1430 Foswiki::Meta->new( $Foswiki::Plugins::SESSION, $web, $topic, $text );
1431 $tmpMeta->copyFrom($meta);
1432 $meta = $tmpMeta;
1433
1434 } # Otherwise meta overrides text - Item2953
1435
1436112µs1365µs return $meta->haveAccess( $type, $cUID );
# spent 365µs making 1 call to Foswiki::Meta::haveAccess
1437}
1438
1439=begin TML
1440
1441---++ Traversing
1442
1443=cut
1444
1445=begin TML
1446
1447---+++ getListOfWebs( $filter [, $web] ) -> @webs
1448
1449 * =$filter= - spec of web types to recover
1450Gets a list of webs, filtered according to the spec in the $filter,
1451which may include one of:
1452 1 'user' (for only user webs)
1453 2 'template' (for only template webs i.e. those starting with "_")
1454=$filter= may also contain the word 'public' which will further filter
1455out webs that have NOSEARCHALL set on them.
1456'allowed' filters out webs the current user can't read.
1457 * =$web= - (*Since* 2009-01-01) name of web to get list of subwebs for. Defaults to the root.
1458
1459For example, the deprecated getPublicWebList function can be duplicated
1460as follows:
1461<verbatim>
1462 my @webs = Foswiki::Func::getListOfWebs( "user,public" );
1463</verbatim>
1464
1465=cut
1466
1467
# spent 8.35s (118µs+8.35) within Foswiki::Func::getListOfWebs which was called 2 times, avg 4.18s/call: # once (79µs+8.33s) by Foswiki::Plugins::ExtendedWebListPlugin::_EXTENDEDWEBLIST at line 155 of /var/www/foswiki11/lib/Foswiki/Plugins/ExtendedWebListPlugin.pm # once (39µs+19.7ms) by Foswiki::Plugins::ExtendedWebListPlugin::_EXTENDEDWEBLIST at line 156 of /var/www/foswiki11/lib/Foswiki/Plugins/ExtendedWebListPlugin.pm
sub getListOfWebs {
146822µs my $filter = shift;
146921µs my $web = shift;
147022µs if ( defined $web ) {
1471217µs252µs $web = _checkWTA($web);
# spent 52µs making 2 calls to Foswiki::Func::_checkWTA, avg 26µs/call
147221µs return () unless defined $web;
1473 }
147426µs25µs ASSERT($Foswiki::Plugins::SESSION) if DEBUG;
# spent 5µs making 2 calls to Assert::ASSERTS_OFF, avg 3µs/call
147524µs require Foswiki::WebFilter;
1476225µs2160µs my $f = new Foswiki::WebFilter( $filter || '' );
# spent 160µs making 2 calls to Foswiki::WebFilter::new, avg 80µs/call
1477245µs28.35s return $Foswiki::Plugins::SESSION->deepWebList( $f, $web );
# spent 8.35s making 2 calls to Foswiki::deepWebList, avg 4.18s/call
1478}
1479
1480=begin TML
1481
1482---+++ isValidWebName( $name [, $system] ) -> $boolean
1483
1484Check for a valid web name. If $system is true, then
1485system web names are considered valid (names starting with _)
1486otherwise only user web names are valid
1487
1488If $Foswiki::cfg{EnableHierarchicalWebs} is off, it will also return false
1489when a nested web name is passed to it.
1490
1491=cut
1492
1493sub isValidWebName {
1494 return Foswiki::isValidWebName(@_);
1495}
1496
1497=begin TML
1498
1499---+++ webExists( $web ) -> $boolean
1500
1501Test if web exists
1502 * =$web= - Web name, required, e.g. ='Sandbox'=
1503
1504=cut
1505
1506sub webExists {
1507 my ($web) = _checkWTA(@_);
1508 return 0 unless defined $web;
1509
1510 ASSERT($Foswiki::Plugins::SESSION) if DEBUG;
1511 return $Foswiki::Plugins::SESSION->webExists($web);
1512}
1513
1514=begin TML
1515
1516---+++ getTopicList( $web ) -> @topics
1517
1518Get list of all topics in a web
1519 * =$web= - Web name, required, e.g. ='Sandbox'=
1520Return: =@topics= Topic list, e.g. =( 'WebChanges', 'WebHome', 'WebIndex', 'WebNotify' )=
1521
1522=cut
1523
1524sub getTopicList {
1525
1526 my ($web) = _validateWTA(@_);
1527
1528 my $webObject = Foswiki::Meta->new( $Foswiki::Plugins::SESSION, $web );
1529 my $it = $webObject->eachTopic();
1530 return $it->all();
1531}
1532
1533=begin TML
1534
1535---+++ isValidTopicName( $name [, $allowNonWW] ) -> $boolean
1536
1537Check for a valid topic name.
1538 * =$name= - topic name
1539 * =$allowNonWW= - true to allow non-wikiwords
1540
1541=cut
1542
1543sub isValidTopicName {
1544 return Foswiki::isValidTopicName(@_);
1545}
1546
1547=begin TML
1548
1549---+++ topicExists( $web, $topic ) -> $boolean
1550
1551Test if topic exists
1552 * =$web= - Web name, optional, e.g. ='Main'=.
1553 * =$topic= - Topic name, required, e.g. ='TokyoOffice'=, or ="Main.TokyoOffice"=
1554
1555$web and $topic are parsed as described in the documentation for =normalizeWebTopicName=.
1556Specifically, the %USERSWEB% is used if $web is not specified and $topic has no web specifier.
1557To get an expected behaviour it is recommened to specify the current web for $web; don't leave it empty.
1558
1559=cut
1560
1561
# spent 169µs (32+137) within Foswiki::Func::topicExists which was called: # once (32µs+137µs) by Foswiki::Plugins::AutoViewTemplatePlugin::initPlugin at line 50 of /var/www/foswiki11/lib/Foswiki/Plugins/AutoViewTemplatePlugin.pm
sub topicExists {
156212µs11µs ASSERT($Foswiki::Plugins::SESSION) if DEBUG;
# spent 1µs making 1 call to Assert::ASSERTS_OFF
156316µs158µs my ( $web, $topic ) = _checkWTA(@_);
# spent 58µs making 1 call to Foswiki::Func::_checkWTA
15641300ns return 0 unless defined $web && defined $topic;
1565110µs178µs return $Foswiki::Plugins::SESSION->topicExists( $web, $topic );
# spent 78µs making 1 call to Foswiki::topicExists
1566}
1567
1568=begin TML
1569
1570---+++ readTopic( $web, $topic, $rev ) -> ( $meta, $text )
1571
1572Read topic text and meta data, regardless of access permissions.
1573 * =$web= - Web name, required, e.g. ='Main'=
1574 * =$topic= - Topic name, required, e.g. ='TokyoOffice'=
1575 * =$rev= - revision to read (default latest)
1576Return: =( $meta, $text )= Meta data object and topic text
1577
1578=$meta= is a perl 'object' of class =Foswiki::Meta=. This class is
1579fully documented in the source code documentation shipped with the
1580release, or can be inspected in the =lib/Foswiki/Meta.pm= file.
1581
1582This method *ignores* topic access permissions. You should be careful to use
1583=checkAccessPermission= to ensure the current user has read access to the
1584topic.
1585
1586=cut
1587
1588
# spent 692µs (34+658) within Foswiki::Func::readTopic which was called: # once (34µs+658µs) by Foswiki::Plugins::AutoViewTemplatePlugin::initPlugin at line 60 of /var/www/foswiki11/lib/Foswiki/Plugins/AutoViewTemplatePlugin.pm
sub readTopic {
1589
159012µs my ( $web, $topic, $rev ) = @_;
159114µs145µs ( $web, $topic ) = _validateWTA( $web, $topic );
# spent 45µs making 1 call to Foswiki::Func::_validateWTA
159212µs11µs ASSERT($Foswiki::Plugins::SESSION) if DEBUG;
# spent 1µs making 1 call to Assert::ASSERTS_OFF
1593
159416µs1599µs my $meta =
# spent 599µs making 1 call to Foswiki::Meta::load
1595 Foswiki::Meta->load( $Foswiki::Plugins::SESSION, $web, $topic, $rev );
1596110µs112µs return ( $meta, $meta->text() );
# spent 12µs making 1 call to Foswiki::Meta::text
1597}
1598
1599=begin TML
1600
1601---+++ getRevisionInfo($web, $topic, $rev, $attachment ) -> ( $date, $user, $rev, $comment )
1602
1603Get revision info of a topic or attachment
1604 * =$web= - Web name, optional, e.g. ='Main'=
1605 * =$topic= - Topic name, required, e.g. ='TokyoOffice'=
1606 * =$rev= - revsion number, or tag name (can be in the format 1.2, or just the minor number)
1607 * =$attachment= -attachment filename
1608Return: =( $date, $user, $rev, $comment )= List with: ( last update date, login name of last user, minor part of top revision number, comment of attachment if attachment ), e.g. =( 1234561, 'phoeny', "5", )=
1609| $date | in epochSec |
1610| $user | Wiki name of the author (*not* login name) |
1611| $rev | actual rev number |
1612| $comment | comment given for uploaded attachment |
1613
1614NOTE: if you are trying to get revision info for a topic, use
1615=$meta->getRevisionInfo= instead if you can - it is significantly
1616more efficient.
1617
1618=cut
1619
1620sub getRevisionInfo {
1621 my ( $web, $topic, $rev, $attachment ) = @_;
1622
1623 ( $web, $topic ) = _validateWTA( $web, $topic );
1624
1625 ASSERT($Foswiki::Plugins::SESSION) if DEBUG;
1626
1627 my $topicObject;
1628 my $info;
1629 if ($attachment) {
1630 $topicObject =
1631 Foswiki::Meta->load( $Foswiki::Plugins::SESSION, $web, $topic );
1632 $info = $topicObject->getAttachmentRevisionInfo( $attachment, $rev );
1633 }
1634 else {
1635 $topicObject =
1636 Foswiki::Meta->load( $Foswiki::Plugins::SESSION, $web, $topic, $rev );
1637 $info = $topicObject->getRevisionInfo();
1638 }
1639 return ( $info->{date},
1640 $Foswiki::Plugins::SESSION->{users}->getWikiName( $info->{author} ),
1641 $info->{version}, $info->{comment} );
1642}
1643
1644=begin TML
1645
1646---+++ getRevisionAtTime( $web, $topic, $time ) -> $rev
1647
1648Get the revision number of a topic at a specific time.
1649 * =$web= - web for topic
1650 * =$topic= - topic
1651 * =$time= - time (in epoch secs) for the rev
1652Return: Single-digit revision number, or undef if it couldn't be determined
1653(either because the topic isn't that old, or there was a problem)
1654
1655=cut
1656
1657sub getRevisionAtTime {
1658 my ( $web, $topic, $time ) = @_;
1659 ( $web, $topic ) = _validateWTA( $web, $topic );
1660 ASSERT($Foswiki::Plugins::SESSION) if DEBUG;
1661 my $topicObject =
1662 Foswiki::Meta->new( $Foswiki::Plugins::SESSION, $web, $topic );
1663 return $topicObject->getRevisionAtTime($time);
1664}
1665
1666=begin TML
1667
1668---+++ getAttachmentList( $web, $topic ) -> @list
1669Get a list of the attachments on the given topic.
1670
1671*Since:* 31 Mar 2009
1672
1673=cut
1674
1675sub getAttachmentList {
1676 my ( $web, $topic ) = @_;
1677 ( $web, $topic ) = _validateWTA( $web, $topic );
1678 my $topicObject =
1679 Foswiki::Meta->new( $Foswiki::Plugins::SESSION, $web, $topic );
1680 my $it = $topicObject->eachAttachment();
1681 return sort $it->all();
1682}
1683
1684=begin TML
1685
1686---+++ attachmentExists( $web, $topic, $attachment ) -> $boolean
1687
1688Test if attachment exists
1689 * =$web= - Web name, optional, e.g. =Main=.
1690 * =$topic= - Topic name, required, e.g. =TokyoOffice=, or =Main.TokyoOffice=
1691 * =$attachment= - attachment name, e.g.=logo.gif=
1692$web and $topic are parsed as described in the documentation for =normalizeWebTopicName=.
1693
1694=cut
1695
1696sub attachmentExists {
1697 my ( $web, $topic, $attachment ) = _checkWTA(@_);
1698 return 0 unless defined $web && defined $topic && defined $attachment;
1699
1700 my $topicObject =
1701 Foswiki::Meta->new( $Foswiki::Plugins::SESSION, $web, $topic );
1702 return $topicObject->hasAttachment($attachment);
1703}
1704
1705=begin TML
1706
1707---+++ readAttachment( $web, $topic, $name, $rev ) -> $data
1708
1709 * =$web= - web for topic - must not be tainted
1710 * =$topic= - topic - must not be tainted
1711 * =$name= - attachment name - must not be tainted
1712 * =$rev= - revision to read (default latest)
1713Read an attachment from the store for a topic, and return it as a string. The
1714names of attachments on a topic can be recovered from the meta-data returned
1715by =readTopic=. If the attachment does not exist, or cannot be read, undef
1716will be returned. If the revision is not specified, the latest version will
1717be returned.
1718
1719View permission on the topic is required for the
1720read to be successful. Access control violations are flagged by a
1721Foswiki::AccessControlException. Permissions are checked for the current user.
1722
1723<verbatim>
1724my( $meta, $text ) = Foswiki::Func::readTopic( $web, $topic );
1725my @attachments = $meta->find( 'FILEATTACHMENT' );
1726foreach my $a ( @attachments ) {
1727 try {
1728 my $data = Foswiki::Func::readAttachment( $web, $topic, $a->{name} );
1729 ...
1730 } catch Foswiki::AccessControlException with {
1731 };
1732}
1733</verbatim>
1734
1735This is the way 99% of extensions will access attachments.
1736See =Foswiki::Meta::openAttachment= for a lower level interface that does
1737not check access controls.
1738
1739=cut
1740
1741sub readAttachment {
1742 my ( $web, $topic, $attachment, $rev ) = @_;
1743
1744 ( $web, $topic, $attachment ) = _validateWTA( $web, $topic, $attachment );
1745
1746 ASSERT($Foswiki::Plugins::SESSION) if DEBUG;
1747 my $result;
1748
1749 my $topicObject =
1750 Foswiki::Meta->new( $Foswiki::Plugins::SESSION, $web, $topic );
1751 unless ( $topicObject->haveAccess('VIEW') ) {
1752 throw Foswiki::AccessControlException( 'VIEW',
1753 $Foswiki::Plugins::SESSION->{user},
1754 $web, $topic, $Foswiki::Meta::reason );
1755 }
1756 my $fh;
1757 try {
1758 $fh = $topicObject->openAttachment( $attachment, '<', version => $rev );
1759 }
1760 catch Error::Simple with {
1761 $fh = undef;
1762 };
1763 return undef unless $fh;
1764 local $/;
1765 my $data = <$fh>;
1766 return $data;
1767}
1768
1769=begin TML
1770
1771---++ Manipulating
1772
1773=cut
1774
1775=begin TML
1776
1777---+++ createWeb( $newWeb, $baseWeb, $opts )
1778
1779 * =$newWeb= is the name of the new web.
1780 * =$baseWeb= is the name of an existing web (a template web). If the base web is a system web, all topics in it will be copied into the new web. If it is a normal web, only topics starting with 'Web' will be copied. If no base web is specified, an empty web (with no topics) will be created. If it is specified but does not exist, an error will be thrown.
1781 * =$opts= is a ref to a hash that contains settings to be modified in
1782the web preferences topic in the new web.
1783
1784<verbatim>
1785use Error qw( :try );
1786use Foswiki::AccessControlException ();
1787
1788try {
1789 Foswiki::Func::createWeb( "Newweb" );
1790} catch Foswiki::AccessControlException with {
1791 my $e = shift;
1792 # see documentation on Foswiki::AccessControlException
1793} catch Error::Simple with {
1794 my $e = shift;
1795 # see documentation on Error::Simple
1796} otherwise {
1797 ...
1798};
1799</verbatim>
1800
1801=cut
1802
1803sub createWeb {
1804 my ( $web, $baseweb, $opts ) = @_;
1805 ($web) = _validateWTA($web);
1806 if ( defined $baseweb ) {
1807 ($baseweb) = _validateWTA($baseweb);
1808 }
1809 ASSERT($Foswiki::Plugins::SESSION) if DEBUG;
1810
1811 my ($parentWeb) = $web =~ m#(.*)/[^/]+$#;
1812
1813 my $rootObject =
1814 Foswiki::Meta->new( $Foswiki::Plugins::SESSION, $parentWeb );
1815 unless ( $rootObject->haveAccess('CHANGE') ) {
1816 throw Foswiki::AccessControlException( 'CHANGE',
1817 $Foswiki::Plugins::SESSION->{user},
1818 $web, '', $Foswiki::Meta::reason );
1819 }
1820
1821 my $baseObject = Foswiki::Meta->new( $Foswiki::Plugins::SESSION, $baseweb );
1822 unless ( $baseObject->haveAccess('VIEW') ) {
1823 throw Foswiki::AccessControlException( 'VIEW',
1824 $Foswiki::Plugins::SESSION->{user},
1825 $web, '', $Foswiki::Meta::reason );
1826 }
1827
1828 my $webObject = Foswiki::Meta->new( $Foswiki::Plugins::SESSION, $web );
1829 $webObject->populateNewWeb( $baseweb, $opts );
1830}
1831
1832=begin TML
1833
1834---+++ moveWeb( $oldName, $newName )
1835
1836Move (rename) a web.
1837
1838<verbatim>
1839use Error qw( :try );
1840use Foswiki::AccessControlException ();
1841
1842try {
1843 Foswiki::Func::moveWeb( "Oldweb", "Newweb" );
1844} catch Foswiki::AccessControlException with {
1845 my $e = shift;
1846 # see documentation on Foswiki::AccessControlException
1847} catch Error::Simple with {
1848 my $e = shift;
1849 # see documentation on Error::Simple
1850} otherwise {
1851 ...
1852};
1853</verbatim>
1854
1855To delete a web, move it to a subweb of =Trash=
1856<verbatim>
1857Foswiki::Func::moveWeb( "Deadweb", "Trash.Deadweb" );
1858</verbatim>
1859
1860=cut
1861
1862sub moveWeb {
1863 ASSERT($Foswiki::Plugins::SESSION) if DEBUG;
1864 my ( $from, $to ) = @_;
1865 ($from) = _validateWTA($from);
1866 ($to) = _validateWTA($to);
1867
1868 $from = Foswiki::Meta->new( $Foswiki::Plugins::SESSION, $from );
1869 $to = Foswiki::Meta->new( $Foswiki::Plugins::SESSION, $to );
1870 return $from->move($to);
1871
1872}
1873
1874=begin TML
1875
1876---+++ checkTopicEditLock( $web, $topic, $script ) -> ( $oopsUrl, $loginName, $unlockTime )
1877
1878Check if a lease has been taken by some other user.
1879 * =$web= Web name, e.g. ="Main"=, or empty
1880 * =$topic= Topic name, e.g. ="MyTopic"=, or ="Main.MyTopic"=
1881Return: =( $oopsUrl, $loginName, $unlockTime )= - The =$oopsUrl= for calling redirectCgiQuery(), user's =$loginName=, and estimated =$unlockTime= in minutes, or ( '', '', 0 ) if no lease exists.
1882 * =$script= The script to invoke when continuing with the edit
1883
1884=cut
1885
1886sub checkTopicEditLock {
1887 my ( $web, $topic, $script ) = @_;
1888 ASSERT($Foswiki::Plugins::SESSION) if DEBUG;
1889
1890 ( $web, $topic ) = _checkWTA( $web, $topic );
1891 return ( '', '', 0 ) unless defined $web && defined $topic;
1892
1893 $script ||= 'edit';
1894
1895 my $topicObject =
1896 Foswiki::Meta->new( $Foswiki::Plugins::SESSION, $web, $topic );
1897 my $lease = $topicObject->getLease();
1898 if ($lease) {
1899 my $remain = $lease->{expires} - time();
1900 my $session = $Foswiki::Plugins::SESSION;
1901
1902 if ( $remain > 0 ) {
1903 my $who = $lease->{user};
1904 require Foswiki::Time;
1905 my $past = Foswiki::Time::formatDelta( time() - $lease->{taken},
1906 $Foswiki::Plugins::SESSION->i18n );
1907 my $future = Foswiki::Time::formatDelta( $lease->{expires} - time(),
1908 $Foswiki::Plugins::SESSION->i18n );
1909 my $url = getScriptUrl(
1910 $web, $topic, 'oops',
1911 template => 'oopsleaseconflict',
1912 def => 'lease_active',
1913 param1 => $who,
1914 param2 => $past,
1915 param3 => $future,
1916 param4 => $script
1917 );
1918 my $login = $session->{users}->getLoginName($who);
1919 return ( $url, $login || $who, $remain / 60 );
1920 }
1921 }
1922 return ( '', '', 0 );
1923}
1924
1925=begin TML
1926
1927---+++ setTopicEditLock( $web, $topic, $lock )
1928
1929 * =$web= Web name, e.g. ="Main"=, or empty
1930 * =$topic= Topic name, e.g. ="MyTopic"=, or ="Main.MyTopic"=
1931 * =$lock= 1 to lease the topic, 0 to clear an existing lease
1932
1933Takes out a "lease" on the topic. The lease doesn't prevent
1934anyone from editing and changing the topic, but it does redirect them
1935to a warning screen, so this provides some protection. The =edit= script
1936always takes out a lease.
1937
1938It is *impossible* to fully lock a topic. Concurrent changes will be
1939merged.
1940
1941=cut
1942
1943sub setTopicEditLock {
1944 my ( $web, $topic, $lock ) = @_;
1945 ASSERT($Foswiki::Plugins::SESSION) if DEBUG;
1946 ( $web, $topic ) = _validateWTA( $web, $topic );
1947 my $topicObject =
1948 Foswiki::Meta->new( $Foswiki::Plugins::SESSION, $web, $topic );
1949 if ($lock) {
1950 $topicObject->setLease( $Foswiki::cfg{LeaseLength} );
1951 }
1952 else {
1953 $topicObject->clearLease();
1954 }
1955 return '';
1956}
1957
1958=begin TML
1959
1960---+++ saveTopic( $web, $topic, $meta, $text, $options )
1961
1962 * =$web= - web for the topic
1963 * =$topic= - topic name
1964 * =$meta= - reference to Foswiki::Meta object
1965 * =$text= - text of the topic (without embedded meta-data!!!
1966 * =\%options= - ref to hash of save options
1967 =\%options= may include:
1968 | =dontlog= | mark this change so it doesn't appear in the statistics |
1969 | =minor= | True if this change is not to be notified |
1970 | =forcenewrevision= | force the save to increment the revision counter |
1971 | =ignorepermissions= | don't check acls |
1972For example,
1973<verbatim>
1974use Error qw( :try );
1975
1976my( $meta, $text ) = Foswiki::Func::readTopic( $web, $topic );
1977$text =~ s/APPLE/ORANGE/g;
1978try {
1979 saveTopic( $web, $topic, $meta, $text );
1980} catch Foswiki::AccessControlException with {
1981 my $e = shift;
1982 # see documentation on Foswiki::AccessControlException
1983} catch Error::Simple with {
1984 my $e = shift;
1985 # see documentation on Error::Simple
1986} otherwise {
1987 ...
1988};
1989</verbatim>
1990
1991In the event of an error an exception will be thrown. Callers can elect
1992to trap the exceptions thrown, or allow them to propagate to the calling
1993environment. May throw Foswiki::OopsException or Error::Simple.
1994
1995*Note:* The =ignorepermissions= option is only available in Foswiki 1.1 and
1996later.
1997
1998=cut
1999
2000sub saveTopic {
2001 my ( $web, $topic, $smeta, $text, $options ) = @_;
2002 ASSERT($Foswiki::Plugins::SESSION) if DEBUG;
2003 ( $web, $topic ) = _validateWTA( $web, $topic );
2004 my $topicObject =
2005 Foswiki::Meta->new( $Foswiki::Plugins::SESSION, $web, $topic );
2006
2007 unless ( $options->{ignorepermissions}
2008 || $topicObject->haveAccess('CHANGE') )
2009 {
2010 throw Foswiki::AccessControlException( 'CHANGE',
2011 $Foswiki::Plugins::SESSION->{user},
2012 $web, $topic, $Foswiki::Meta::reason );
2013 }
2014
2015 # Set the new text and meta, now that access to the existing topic
2016 # is verified
2017 $topicObject->text($text);
2018 $topicObject->copyFrom($smeta) if $smeta;
2019 return $topicObject->save(%$options);
2020}
2021
2022=begin TML
2023
2024---+++ moveTopic( $web, $topic, $newWeb, $newTopic )
2025
2026 * =$web= source web - required
2027 * =$topic= source topic - required
2028 * =$newWeb= dest web
2029 * =$newTopic= dest topic
2030Renames the topic. Throws an exception if something went wrong.
2031If $newWeb is undef, it defaults to $web. If $newTopic is undef, it defaults
2032to $topic.
2033
2034The destination topic must not already exist.
2035
2036Rename a topic to the $Foswiki::cfg{TrashWebName} to delete it.
2037
2038<verbatim>
2039use Error qw( :try );
2040
2041try {
2042 moveTopic( "Work", "TokyoOffice", "Trash", "ClosedOffice" );
2043} catch Foswiki::AccessControlException with {
2044 my $e = shift;
2045 # see documentation on Foswiki::AccessControlException
2046} catch Error::Simple with {
2047 my $e = shift;
2048 # see documentation on Error::Simple
2049} otherwise {
2050 ...
2051};
2052</verbatim>
2053
2054=cut
2055
2056sub moveTopic {
2057 my ( $web, $topic, $newWeb, $newTopic ) = @_;
2058 ( $web, $topic ) = _validateWTA( $web, $topic );
2059 ( $newWeb, $newTopic ) =
2060 _validateWTA( $newWeb || $web, $newTopic || $topic );
2061
2062 return if ( $newWeb eq $web && $newTopic eq $topic );
2063
2064 my $from = Foswiki::Meta->new( $Foswiki::Plugins::SESSION, $web, $topic );
2065 unless ( $from->haveAccess('CHANGE') ) {
2066 throw Foswiki::AccessControlException( 'CHANGE',
2067 $Foswiki::Plugins::SESSION->{user},
2068 $web, $topic, $Foswiki::Meta::reason );
2069 }
2070
2071 my $toWeb = Foswiki::Meta->new( $Foswiki::Plugins::SESSION, $newWeb );
2072 unless ( $from->haveAccess('CHANGE') ) {
2073 throw Foswiki::AccessControlException( 'CHANGE',
2074 $Foswiki::Plugins::SESSION->{user},
2075 $newWeb, undef, $Foswiki::Meta::reason );
2076 }
2077
2078 my $to =
2079 Foswiki::Meta->new( $Foswiki::Plugins::SESSION, $newWeb, $newTopic );
2080
2081 $from->move($to);
2082}
2083
2084=begin TML
2085
2086---+++ saveAttachment( $web, $topic, $attachment, \%opts )
2087 * =$web= - web for topic
2088 * =$topic= - topic to atach to
2089 * =$attachment= - name of the attachment
2090 * =\%opts= - Ref to hash of options
2091Create an attachment on the given topic.
2092=\%opts= may include:
2093| =dontlog= | mark this change so it is not picked up in statistics |
2094| =comment= | comment for save |
2095| =hide= | if the attachment is to be hidden in normal topic view |
2096| =stream= | Stream of file to upload |
2097| =file= | Name of a file to use for the attachment data. ignored if stream is set. Local file on the server. |
2098| =filepath= | Client path to file |
2099| =filesize= | Size of uploaded data |
2100| =filedate= | Date |
2101| =createlink= | Set true to create a link at the end of the topic |
2102| =notopicchange= | Set to true to *prevent* this upload being recorded in the meta-data of the topic. |
2103Save an attachment to the store for a topic. On success, returns undef.
2104If there is an error, an exception will be thrown. The current user must
2105have CHANGE access on the topic being attached to.
2106
2107<verbatim>
2108 try {
2109 Foswiki::Func::saveAttachment( $web, $topic, 'image.gif',
2110 { file => 'image.gif',
2111 comment => 'Picture of Health',
2112 hide => 1 } );
2113 } catch Foswiki::AccessControlException with {
2114 # Topic CHANGE access denied
2115 } catch Error::Simple with {
2116 # see documentation on Error
2117 } otherwise {
2118 ...
2119 };
2120</verbatim>
2121This is the way 99% of extensions will create new attachments. See
2122=Foswiki::Meta::openAttachment= for a much lower-level interface.
2123
2124=cut
2125
2126sub saveAttachment {
2127 my ( $web, $topic, $attachment, $data ) = @_;
2128 ( $web, $topic, $attachment ) = _validateWTA( $web, $topic, $attachment );
2129
2130 ASSERT($Foswiki::Plugins::SESSION) if DEBUG;
2131 my $topicObject =
2132 Foswiki::Meta->new( $Foswiki::Plugins::SESSION, $web, $topic );
2133 unless ( $topicObject->haveAccess('CHANGE') ) {
2134 throw Foswiki::AccessControlException( 'CHANGE',
2135 $Foswiki::Plugins::SESSION->{user},
2136 $web, $topic, $Foswiki::Meta::reason );
2137 }
2138 $topicObject->attach( name => $attachment, %$data );
2139}
2140
2141=begin TML
2142
2143---+++ moveAttachment( $web, $topic, $attachment, $newWeb, $newTopic, $newAttachment )
2144
2145 * =$web= source web - required
2146 * =$topic= source topic - required
2147 * =$attachment= source attachment - required
2148 * =$newWeb= dest web
2149 * =$newTopic= dest topic
2150 * =$newAttachment= dest attachment
2151Renames the attachment. Throws an exception on error or access violation.
2152If $newWeb is undef, it defaults to $web. If $newTopic is undef, it defaults
2153to $topic. If $newAttachment is undef, it defaults to $attachment. If all of $newWeb, $newTopic and $newAttachment are undef, it is an error.
2154
2155The destination topic must already exist, but the destination attachment must
2156*not* exist.
2157
2158Rename an attachment to $Foswiki::cfg{TrashWebName}.TrashAttament to delete it.
2159
2160<verbatim>
2161use Error qw( :try );
2162
2163try {
2164 # move attachment between topics
2165 moveAttachment( "Countries", "Germany", "AlsaceLorraine.dat",
2166 "Countries", "France" );
2167 # Note destination attachment name is defaulted to the same as source
2168} catch Foswiki::AccessControlException with {
2169 my $e = shift;
2170 # see documentation on Foswiki::AccessControlException
2171} catch Error::Simple with {
2172 my $e = shift;
2173 # see documentation on Error::Simple
2174};
2175</verbatim>
2176
2177=cut
2178
2179sub moveAttachment {
2180 my ( $web, $topic, $attachment, $newWeb, $newTopic, $newAttachment ) = @_;
2181
2182 ( $web, $topic, $attachment ) = _validateWTA( $web, $topic, $attachment );
2183
2184 ( $newWeb, $newTopic, $newAttachment ) = _validateWTA(
2185 $newWeb || $web,
2186 $newTopic || $topic,
2187 $newAttachment || $attachment
2188 );
2189
2190 return
2191 if ( $newWeb eq $web
2192 && $newTopic eq $topic
2193 && $newAttachment eq $attachment );
2194
2195 my $from = Foswiki::Meta->load( $Foswiki::Plugins::SESSION, $web, $topic );
2196 unless ( $from->haveAccess('CHANGE') ) {
2197 throw Foswiki::AccessControlException( 'CHANGE',
2198 $Foswiki::Plugins::SESSION->{user},
2199 $web, $topic, $Foswiki::Meta::reason );
2200 }
2201 my @opts;
2202 push( @opts, new_name => $newAttachment ) if defined $newAttachment;
2203
2204 if ( $web eq $newWeb
2205 && $topic eq $newTopic
2206 && defined $newAttachment )
2207 {
2208 $from->moveAttachment( $attachment, $from, @opts );
2209 }
2210 else {
2211 my $to =
2212 Foswiki::Meta->load( $Foswiki::Plugins::SESSION, $newWeb, $newTopic );
2213 unless ( $to->haveAccess('CHANGE') ) {
2214 throw Foswiki::AccessControlException( 'CHANGE',
2215 $Foswiki::Plugins::SESSION->{user},
2216 $newWeb, $newTopic, $Foswiki::Meta::reason );
2217 }
2218
2219 $from->moveAttachment( $attachment, $to, @opts );
2220 }
2221}
2222
2223=begin TML
2224
2225---+++ copyAttachment( $web, $topic, $attachment, $newWeb, $newTopic, $newAttachment )
2226
2227 * =$web= source web - required
2228 * =$topic= source topic - required
2229 * =$attachment= source attachment - required
2230 * =$newWeb= dest web
2231 * =$newTopic= dest topic
2232 * =$newAttachment= dest attachment
2233Copies the attachment. Throws an exception on error or access violation.
2234If $newWeb is undef, it defaults to $web. If $newTopic is undef, it defaults
2235to $topic. If $newAttachment is undef, it defaults to $attachment. If all of $newWeb, $newTopic and $newAttachment are undef, it is an error.
2236
2237The destination topic must already exist, but the destination attachment must
2238*not* exist.
2239
2240Rename an attachment to $Foswiki::cfg{TrashWebName}.TrashAttament to delete it.
2241
2242<verbatim>
2243use Error qw( :try );
2244
2245try {
2246 # copy attachment between topics
2247 copyAttachment( "Countries", "Germany", "AlsaceLorraine.dat",
2248 "Countries", "France" );
2249 # Note destination attachment name is defaulted to the same as source
2250} catch Foswiki::AccessControlException with {
2251 my $e = shift;
2252 # see documentation on Foswiki::AccessControlException
2253} catch Error::Simple with {
2254 my $e = shift;
2255 # see documentation on Error::Simple
2256};
2257</verbatim>
2258
2259*Since:* 19 Jul 2010
2260
2261=cut
2262
2263sub copyAttachment {
2264 my ( $web, $topic, $attachment, $newWeb, $newTopic, $newAttachment ) = @_;
2265
2266 ( $web, $topic, $attachment ) = _validateWTA( $web, $topic, $attachment );
2267
2268 ( $newWeb, $newTopic, $newAttachment ) = _validateWTA(
2269 $newWeb || $web,
2270 $newTopic || $topic,
2271 $newAttachment || $attachment
2272 );
2273
2274 return
2275 if ( $newWeb eq $web
2276 && $newTopic eq $topic
2277 && $newAttachment eq $attachment );
2278
2279 my $from = Foswiki::Meta->load( $Foswiki::Plugins::SESSION, $web, $topic );
2280 unless ( $from->haveAccess('CHANGE') ) {
2281 throw Foswiki::AccessControlException( 'CHANGE',
2282 $Foswiki::Plugins::SESSION->{user},
2283 $web, $topic, $Foswiki::Meta::reason );
2284 }
2285 my @opts;
2286 push( @opts, new_name => $newAttachment ) if defined $newAttachment;
2287
2288 if ( $web eq $newWeb
2289 && $topic eq $newTopic
2290 && defined $newAttachment )
2291 {
2292 $from->copyAttachment( $attachment, $from, @opts );
2293 }
2294 else {
2295 my $to =
2296 Foswiki::Meta->load( $Foswiki::Plugins::SESSION, $newWeb, $newTopic );
2297 unless ( $to->haveAccess('CHANGE') ) {
2298 throw Foswiki::AccessControlException( 'CHANGE',
2299 $Foswiki::Plugins::SESSION->{user},
2300 $newWeb, $newTopic, $Foswiki::Meta::reason );
2301 }
2302
2303 $from->copyAttachment( $attachment, $to, @opts );
2304 }
2305}
2306
2307=begin TML
2308
2309---++ Finding changes
2310
2311=cut
2312
2313=begin TML
2314
2315---+++ eachChangeSince($web, $time) -> $iterator
2316
2317Get an iterator over the list of all the changes in the given web between
2318=$time= and now. $time is a time in seconds since 1st Jan 1970, and is not
2319guaranteed to return any changes that occurred before (now -
2320{Store}{RememberChangesFor}). {Store}{RememberChangesFor}) is a
2321setting in =configure=. Changes are returned in *most-recent-first*
2322order.
2323
2324Use it as follows:
2325<verbatim>
2326 my $iterator = Foswiki::Func::eachChangeSince(
2327 $web, time() - 7 * 24 * 60 * 60); # the last 7 days
2328 while ($iterator->hasNext()) {
2329 my $change = $iterator->next();
2330 # $change is a perl hash that contains the following fields:
2331 # topic => topic name
2332 # user => wikiname - wikiname of user who made the change
2333 # time => time of the change
2334 # revision => revision number *after* the change
2335 # more => more info about the change (e.g. 'minor')
2336 }
2337</verbatim>
2338
2339=cut
2340
2341sub eachChangeSince {
2342 my ( $web, $time ) = @_;
2343 ASSERT($Foswiki::Plugins::SESSION) if DEBUG;
2344 ($web) = _validateWTA($web);
2345 ASSERT( $Foswiki::Plugins::SESSION->webExists($web) ) if DEBUG;
2346
2347 my $webObject = Foswiki::Meta->new( $Foswiki::Plugins::SESSION, $web );
2348
2349 # eachChange returns changes with cUIDs. these have to be mapped
2350 # to wikinames per the Foswiki::Func 'spec' (changes used to be stored
2351 # with wikinames)
2352 require Foswiki::Iterator::ProcessIterator;
2353 require Foswiki::Users::BaseUserMapping;
2354 return new Foswiki::Iterator::ProcessIterator(
2355 $webObject->eachChange($time),
2356 sub {
2357 my $n = shift;
2358 $n->{user} = $Foswiki::Users::BaseUserMapping::UNKNOWN_USER_CUID
2359 unless defined $n->{user};
2360 $n->{user} =
2361 $Foswiki::Plugins::SESSION->{users}->getWikiName( $n->{user} );
2362 return $n;
2363 }
2364 );
2365}
2366
2367=begin TML
2368
2369---+++ summariseChanges($web, $topic, $orev, $nrev, $tml) -> $text
2370Generate a summary of the changes between rev $orev and rev $nrev of the
2371given topic.
2372 * =$web=, =$topic= - topic (required)
2373 * =$orev= - older rev (required)
2374 * =$nrev= - later rev (may be undef for the latest)
2375 * =$tml= - if true will generate renderable TML (i.e. HTML with NOPs. if false will generate a summary suitable for use in plain text (mail, for example)
2376Generate a (max 3 line) summary of the differences between the revs.
2377
2378If there is only one rev, a topic summary will be returned.
2379
2380If =$tml= is not set, all HTML will be removed.
2381
2382In non-tml, lines are truncated to 70 characters. Differences are shown using + and - to indicate added and removed text.
2383
2384If access is denied to either revision, then it will be treated as blank
2385text.
2386
2387*Since* 2009-03-06
2388
2389=cut
2390
2391sub summariseChanges {
2392 my ( $web, $topic, $orev, $nrev, $tml ) = @_;
2393 ( $web, $topic ) = _validateWTA( $web, $topic );
2394
2395 my $topicObject =
2396 Foswiki::Meta->new( $Foswiki::Plugins::SESSION, $web, $topic );
2397 return $topicObject->summariseChanges( Foswiki::Store::cleanUpRevID($orev),
2398 Foswiki::Store::cleanUpRevID($nrev), $tml );
2399}
2400
2401=begin TML
2402
2403---++ Templates
2404
2405=cut
2406
2407=begin TML
2408
2409---+++ readTemplate( $name, $skin ) -> $text
2410
2411Read a template or skin. Embedded [[%SYSTEMWEB%.SkinTemplates][template directives]] get expanded
2412 * =$name= - Template name, e.g. ='view'=
2413 * =$skin= - Comma-separated list of skin names, optional, e.g. ='print'=
2414Return: =$text= Template text
2415
2416=cut
2417
2418sub readTemplate {
2419
2420 my ( $name, $skin ) = @_;
2421 ASSERT($Foswiki::Plugins::SESSION) if DEBUG;
2422 return $Foswiki::Plugins::SESSION->templates->readTemplate(
2423 $name,
2424 skins => $skin,
2425 no_oops => 1
2426 ) || '';
2427}
2428
2429=begin TML
2430
2431---+++ loadTemplate ( $name, $skin, $web ) -> $text
2432
2433 * =$name= - template file name
2434 * =$skin= - comma-separated list of skins to use (default: current skin)
2435 * =$web= - the web to look in for topics that contain templates (default: current web)
2436Return: expanded template text (what's left after removal of all %TMPL:DEF% statements)
2437
2438Reads a template and extracts template definitions, adding them to the
2439list of loaded templates, overwriting any previous definition.
2440
2441How Foswiki searches for templates is described in SkinTemplates.
2442
2443If template text is found, extracts include statements and fully expands them.
2444
2445=cut
2446
2447sub loadTemplate {
2448 ASSERT($Foswiki::Plugins::SESSION) if DEBUG;
2449 my ( $name, $skin, $web ) = @_;
2450
2451 my %opts = ( no_oops => 1 );
2452 $opts{skins} = $skin if defined $skin;
2453 ( $opts{web} ) = _validateWTA($web) if defined $web;
2454
2455 my $tmpl =
2456 $Foswiki::Plugins::SESSION->templates->readTemplate( $name, %opts );
2457 $tmpl = '' unless defined $tmpl;
2458
2459 return $tmpl;
2460}
2461
2462=begin TML
2463
2464---+++ expandTemplate( $def ) -> $string
2465
2466Do a =%<nop>TMPL:P{$def}%=, only expanding the template (not expanding any variables other than =%TMPL%=.)
2467 * =$def= - template name or parameters (as a string)
2468Return: the text of the expanded template
2469
2470A template is defined using a =%TMPL:DEF%= statement in a template
2471file. See the [[System.SkinTemplates][documentation on Foswiki templates]] for more information.
2472
2473eg:
2474 #load the templates (relying on the system-wide skin path.)
2475 Foswiki::Func::loadTemplate('linkedin');
2476 #get the 'profile' DEF section
2477 my $tml = Foswiki::Func::expandTemplate('profile');
2478 #get the 'profile' DEF section expanding the inline Template macros (such as %USER% and %TYPE%)
2479 #NOTE: when using it this way, it is important to use the double quotes "" to delineate the values of the parameters.
2480 my $tml = Foswiki::Func::expandTemplate(
2481 '"profile" USER="' . $user . '" TYPE="' . $type . '"' );
2482
2483=cut
2484
2485sub expandTemplate {
2486 ASSERT($Foswiki::Plugins::SESSION) if DEBUG;
2487 return $Foswiki::Plugins::SESSION->templates->expandTemplate(@_);
2488}
2489
2490=begin TML
2491
2492---++ Rendering
2493
2494=cut
2495
2496=begin TML
2497
2498---+++ expandCommonVariables( $text, $topic, $web, $meta ) -> $text
2499
2500Expand all common =%<nop>VARIABLES%=
2501 * =$text= - Text with variables to expand, e.g. ='Current user is %<nop>WIKIUSER%'=
2502 * =$topic= - Current topic name, e.g. ='WebNotify'=
2503 * =$web= - Web name, optional, e.g. ='Main'=. The current web is taken if missing
2504 * =$meta= - topic meta-data to use while expanding
2505Return: =$text= Expanded text, e.g. ='Current user is <nop>WikiGuest'=
2506
2507See also: expandVariablesOnTopicCreation
2508
2509*Caution:* This function needs all the installed plugins to have gone through initialization.
2510Never call this function from within an initPlugin handler, bad things happen.
2511
2512=cut
2513
2514
# spent 1.21ms (44µs+1.17) within Foswiki::Func::expandCommonVariables which was called 2 times, avg 605µs/call: # once (29µs+622µs) by Foswiki::Plugins::TablePlugin::_readPluginSettings at line 141 of /var/www/foswiki11/lib/Foswiki/Plugins/TablePlugin.pm # once (16µs+544µs) by Foswiki::Plugins::TablePlugin::_readPluginSettings at line 145 of /var/www/foswiki11/lib/Foswiki/Plugins/TablePlugin.pm
sub expandCommonVariables {
251523µs my ( $text, $topic, $web, $meta ) = @_;
251622µs22µs ASSERT($Foswiki::Plugins::SESSION) if DEBUG;
# spent 2µs making 2 calls to Assert::ASSERTS_OFF, avg 750ns/call
2517
251822µs21µs if (DEBUG) {
# spent 1µs making 2 calls to Assert::ASSERTS_OFF, avg 650ns/call
2519 for ( my $i = 4 ; $i <= 7 ; $i++ ) {
2520 my $caller = ( caller($i) )[3];
2521 ASSERT( 0, "expandCommonVariables called during registration" )
2522 if ( defined $caller
2523 && $caller eq 'Foswiki::Plugin::registerHandlers' );
2524 }
2525 }
2526
252727µs268µs ( $web, $topic ) = _validateWTA(
# spent 68µs making 2 calls to Foswiki::Func::_validateWTA, avg 34µs/call
2528 $web || $Foswiki::Plugins::SESSION->{webName},
2529 $topic || $Foswiki::Plugins::SESSION->{topicName}
2530 );
253127µs236µs $meta ||= Foswiki::Meta->new( $Foswiki::Plugins::SESSION, $web, $topic );
# spent 36µs making 2 calls to Foswiki::Meta::new, avg 18µs/call
2532
2533213µs21.06ms return $meta->expandMacros($text);
# spent 1.06ms making 2 calls to Foswiki::Meta::expandMacros, avg 530µs/call
2534}
2535
2536=begin TML
2537
2538---+++ expandVariablesOnTopicCreation ( $text ) -> $text
2539
2540Expand the limited set of variables that are always expanded during topic creation
2541 * =$text= - the text to process
2542Return: text with variables expanded
2543
2544Expands only the variables expected in templates that must be statically
2545expanded in new content.
2546
2547The expanded variables are:
2548 * =%<nop>DATE%= Signature-format date
2549 * =%<nop>SERVERTIME%= See [[Macros]]
2550 * =%<nop>GMTIME%= See [[Macros]]
2551 * =%<nop>USERNAME%= Base login name
2552 * =%<nop>WIKINAME%= Wiki name
2553 * =%<nop>WIKIUSERNAME%= Wiki name with prepended web
2554 * =%<nop>URLPARAM{...}%= - Parameters to the current CGI query
2555 * =%<nop>NOP%= No-op
2556
2557See also: expandVariables
2558
2559=cut
2560
2561sub expandVariablesOnTopicCreation {
2562 ASSERT($Foswiki::Plugins::SESSION) if DEBUG;
2563 my $topicObject = Foswiki::Meta->new(
2564 $Foswiki::Plugins::SESSION,
2565 $Foswiki::Plugins::SESSION->{webName},
2566 $Foswiki::Plugins::SESSION->{topicName}, $_[0]
2567 );
2568 $topicObject->expandNewTopic();
2569 return $topicObject->text();
2570}
2571
2572=begin TML
2573
2574---+++ renderText( $text, $web, $topic ) -> $text
2575
2576Render text from TML into XHTML as defined in [[%SYSTEMWEB%.TextFormattingRules]]
2577 * =$text= - Text to render, e.g. ='*bold* text and =fixed font='=
2578 * =$web= - Web name, optional, e.g. ='Main'=. The current web is taken if missing
2579 * =$topic= - topic name, optional, defaults to web home
2580Return: =$text= XHTML text, e.g. ='&lt;b>bold&lt;/b> and &lt;code>fixed font&lt;/code>'=
2581
2582NOTE: renderText expects that all %MACROS% have already been expanded - it does not expand them for you.
2583
2584=cut
2585
2586sub renderText {
2587
2588 my ( $text, $web, $topic ) = @_;
2589 ASSERT($Foswiki::Plugins::SESSION) if DEBUG;
2590 $web ||= $Foswiki::Plugins::SESSION->{webName};
2591 $topic ||= $Foswiki::cfg{HomeTopicName};
2592 my $webObject =
2593 Foswiki::Meta->new( $Foswiki::Plugins::SESSION, $web, $topic );
2594 return $webObject->renderTML($text);
2595}
2596
2597=begin TML
2598
2599---+++ internalLink( $pre, $web, $topic, $label, $anchor, $createLink ) -> $text
2600
2601Render topic name and link label into an XHTML link. Normally you do not need to call this funtion, it is called internally by =renderText()=
2602 * =$pre= - Text occuring before the link syntax, optional
2603 * =$web= - Web name, required, e.g. ='Main'=
2604 * =$topic= - Topic name to link to, required, e.g. ='WebNotify'=
2605 * =$label= - Link label, required. Usually the same as =$topic=, e.g. ='notify'=
2606 * =$anchor= - Anchor, optional, e.g. ='#Jump'=
2607 * =$createLink= - Set to ='1'= to add question linked mark after topic name if topic does not exist;<br /> set to ='0'= to suppress link for non-existing topics
2608Return: =$text= XHTML anchor, e.g. ='&lt;a href='/cgi-bin/view/Main/WebNotify#Jump'>notify&lt;/a>'=
2609
2610=cut
2611
2612sub internalLink {
2613 my $pre = shift;
2614 ASSERT($Foswiki::Plugins::SESSION) if DEBUG;
2615
2616 # my( $web, $topic, $label, $anchor, $anchor, $createLink ) = @_;
2617 return $pre . $Foswiki::Plugins::SESSION->renderer->internalLink(@_);
2618}
2619
2620=begin TML
2621
2622---+++ addToZone( $zone, $id, $data, $requires )
2623
2624Direct interface to %<nop>ADDTOZONE (see %SYSTEMWEB%.VarADDTOZONE)
2625
2626 * =$zone= - name of the zone
2627 * =$id= - unique ID
2628 * =$data= - the content.
2629 * =requires= optional, comma-separated list of =$id= identifiers that should
2630 precede the content
2631
2632All macros present in =$data= will be expanded before being inserted into the =&lt;head>= section.
2633
2634<blockquote class="foswikiHelp">%X%
2635*Note:* Read the developer supplement at Foswiki:Development.AddToZoneFromPluginHandlers if you are
2636calling =addToZone()= from a rendering or macro/tag-related plugin handler
2637</blockquote>
2638
2639Examples:
2640<verbatim>
2641Foswiki::Func::addToZone( 'head', 'PATTERN_STYLE',
2642 '<link rel="stylesheet" type="text/css" href="%PUBURL%/Foswiki/PatternSkin/layout.css" media="all" />');
2643
2644Foswiki::Func::addToZone( 'script', 'MY_JQUERY',
2645 '<script type="text/javascript" src="%PUBURL%/Myweb/MyJQuery/myjquery.js"></scipt>',
2646 'JQUERYPLUGIN::FOSWIKI');
2647</verbatim>
2648
2649=cut=
2650
2651
# spent 356µs (110+246) within Foswiki::Func::addToZone which was called 12 times, avg 30µs/call: # 2 times (15µs+52µs) by Foswiki::Plugins::JQueryPlugin::Plugin::init at line 125 of /var/www/foswiki11/lib/Foswiki/Plugins/JQueryPlugin/Plugin.pm, avg 33µs/call # 2 times (13µs+39µs) by Foswiki::Plugins::JQueryPlugin::Plugin::init at line 128 of /var/www/foswiki11/lib/Foswiki/Plugins/JQueryPlugin/Plugin.pm, avg 26µs/call # once (20µs+32µs) by Foswiki::Contrib::JSCalendarContrib::addHEAD at line 214 of /var/www/foswiki11/lib/Foswiki/Contrib/JSCalendarContrib.pm # once (16µs+27µs) by Foswiki::Plugins::JQueryPlugin::Plugins::createTheme at line 149 of /var/www/foswiki11/lib/Foswiki/Plugins/JQueryPlugin/Plugins.pm # once (8µs+20µs) by Foswiki::Contrib::JSCalendarContrib::addHEAD at line 219 of /var/www/foswiki11/lib/Foswiki/Contrib/JSCalendarContrib.pm # once (8µs+16µs) by Foswiki::Plugins::JQueryPlugin::FOSWIKI::init at line 90 of /var/www/foswiki11/lib/Foswiki/Plugins/JQueryPlugin/FOSWIKI.pm # once (8µs+16µs) by Foswiki::Contrib::JSCalendarContrib::addHEAD at line 228 of /var/www/foswiki11/lib/Foswiki/Contrib/JSCalendarContrib.pm # once (8µs+15µs) by Foswiki::Contrib::JSCalendarContrib::addHEAD at line 216 of /var/www/foswiki11/lib/Foswiki/Contrib/JSCalendarContrib.pm # once (7µs+15µs) by Foswiki::Plugins::JQueryPlugin::Plugins::init at line 81 of /var/www/foswiki11/lib/Foswiki/Plugins/JQueryPlugin/Plugins.pm # once (6µs+14µs) by Foswiki::Plugins::TwistyPlugin::_exportAnimationSpeed at line 70 of /var/www/foswiki11/lib/Foswiki/Plugins/TwistyPlugin.pm
sub addToZone {
2652
2653 #my ( $zone, $tag, $data, $requires ) = @_;
2654124µs my $session = $Foswiki::Plugins::SESSION;
26551215µs1212µs ASSERT($session) if DEBUG;
# spent 12µs making 12 calls to Assert::ASSERTS_OFF, avg 1µs/call
2656
26571276µs12234µs $session->addToZone(@_);
# spent 234µs making 12 calls to Foswiki::addToZone, avg 19µs/call
2658}
2659
2660=begin TML
2661
2662---++ Controlling page output
2663
2664=cut
2665
2666=begin TML
2667
2668---+++ writeHeader()
2669
2670Prints a basic content-type HTML header for text/html to standard out.
2671
2672=cut
2673
2674sub writeHeader {
2675 ASSERT($Foswiki::Plugins::SESSION) if DEBUG;
2676 $Foswiki::Plugins::SESSION->generateHTTPHeaders();
2677}
2678
2679=begin TML
2680
2681---+++ redirectCgiQuery( $query, $url, $passthru )
2682
2683Redirect to URL
2684 * =$query= - CGI query object. Ignored, only there for compatibility. The session CGI query object is used instead.
2685 * =$url= - URL to redirect to
2686 * =$passthru= - enable passthrough.
2687
2688Return: none
2689
2690Print output to STDOUT that will cause a 302 redirect to a new URL.
2691Nothing more should be printed to STDOUT after this method has been called.
2692
2693The =$passthru= parameter allows you to pass the parameters that were passed
2694to the current query on to the target URL, as long as it is another URL on the
2695same installation. If =$passthru= is set to a true value, then Foswiki
2696will save the current URL parameters, and then try to restore them on the
2697other side of the redirect. Parameters are stored on the server in a cache
2698file.
2699
2700Note that if =$passthru= is set, then any parameters in =$url= will be lost
2701when the old parameters are restored. if you want to change any parameter
2702values, you will need to do that in the current CGI query before redirecting
2703e.g.
2704<verbatim>
2705my $query = Foswiki::Func::getRequestObject();
2706$query->param(-name => 'text', -value => 'Different text');
2707Foswiki::Func::redirectCgiQuery(
2708 undef, Foswiki::Func::getScriptUrl($web, $topic, 'edit'), 1);
2709</verbatim>
2710=$passthru= does nothing if =$url= does not point to a script in the current
2711Foswiki installation.
2712
2713=cut
2714
2715sub redirectCgiQuery {
2716 my ( $query, $url, $passthru ) = @_;
2717 ASSERT($Foswiki::Plugins::SESSION) if DEBUG;
2718 return $Foswiki::Plugins::SESSION->redirect( $url, $passthru );
2719}
2720
2721=begin TML
2722
2723---++ Plugin-specific file handling
2724
2725=cut
2726
2727=begin TML
2728
2729---+++ getWorkArea( $pluginName ) -> $directorypath
2730
2731Gets a private directory for Plugin use. The Plugin is entirely responsible
2732for managing this directory; Foswiki will not read from it, or write to it.
2733
2734The directory is guaranteed to exist, and to be writable by the webserver
2735user. By default it will *not* be web accessible.
2736
2737The directory and its contents are permanent, so Plugins must be careful
2738to keep their areas tidy.
2739
2740=cut
2741
2742
# spent 134µs (19+115) within Foswiki::Func::getWorkArea which was called: # once (19µs+115µs) by Foswiki::Plugins::DirectedGraphPlugin::_loadHashCodes at line 1060 of /var/www/foswiki11/lib/Foswiki/Plugins/DirectedGraphPlugin.pm
sub getWorkArea {
274312µs my ($plugin) = @_;
274414µs14µs ASSERT($Foswiki::Plugins::SESSION) if DEBUG;
# spent 4µs making 1 call to Assert::ASSERTS_OFF
2745110µs1111µs return $Foswiki::Plugins::SESSION->getWorkArea($plugin);
# spent 111µs making 1 call to Foswiki::getWorkArea
2746}
2747
2748=begin TML
2749
2750---+++ readFile( $filename ) -> $text
2751
2752Read file, low level. Used for Plugin workarea.
2753 * =$filename= - Full path name of file
2754Return: =$text= Content of file, empty if not found
2755
2756__NOTE:__ Use this function only for the Plugin workarea, *not* for topics and attachments. Use the appropriate functions to manipulate topics and attachments.
2757
2758=cut
2759
2760sub readFile {
2761 my $name = shift;
2762 my $data = '';
2763 my $IN_FILE;
2764 open( $IN_FILE, '<', $name ) || return '';
2765 local $/ = undef; # set to read to EOF
2766 $data = <$IN_FILE>;
2767 close($IN_FILE);
2768 $data = '' unless $data; # no undefined
2769 return $data;
2770}
2771
2772=begin TML
2773
2774---+++ saveFile( $filename, $text )
2775
2776Save file, low level. Used for Plugin workarea.
2777 * =$filename= - Full path name of file
2778 * =$text= - Text to save
2779Return: none
2780
2781__NOTE:__ Use this function only for the Plugin workarea, *not* for topics and attachments. Use the appropriate functions to manipulate topics and attachments.
2782
2783=cut
2784
2785sub saveFile {
2786 my ( $name, $text ) = @_;
2787 my $FILE;
2788 unless ( open( $FILE, '>', $name ) ) {
2789 die "Can't create file $name - $!\n";
2790 }
2791 print $FILE $text;
2792 close($FILE);
2793}
2794
2795=begin TML
2796
2797---++ General Utilities
2798
2799=cut
2800
2801=begin TML
2802
2803---+++ normalizeWebTopicName($web, $topic) -> ($web, $topic)
2804
2805Parse a web and topic name, supplying defaults as appropriate.
2806 * =$web= - Web name, identifying variable, or empty string
2807 * =$topic= - Topic name, may be a web.topic string, required.
2808Return: the parsed Web/Topic pair
2809
2810| *Input* | *Return* |
2811| <tt>( 'Web', 'Topic' ) </tt> | <tt>( 'Web', 'Topic' ) </tt> |
2812| <tt>( '', 'Topic' ) </tt> | <tt>( 'Main', 'Topic' ) </tt> |
2813| <tt>( '', '' ) </tt> | <tt>( 'Main', 'WebHome' ) </tt> |
2814| <tt>( '', 'Web/Topic' ) </tt> | <tt>( 'Web', 'Topic' ) </tt> |
2815| <tt>( '', 'Web/Subweb/Topic' ) </tt> | <tt>( 'Web/Subweb', 'Topic' ) </tt> |
2816| <tt>( '', 'Web.Topic' ) </tt> | <tt>( 'Web', 'Topic' ) </tt> |
2817| <tt>( '', 'Web.Subweb.Topic' ) </tt> | <tt>( 'Web/Subweb', 'Topic' ) </tt> |
2818| <tt>( 'Web1', 'Web2.Topic' )</tt> | <tt>( 'Web2', 'Topic' ) </tt> |
2819
2820Note that sub web names (Web.SubWeb) are only available if hierarchical webs are enabled in =configure=.
2821
2822The symbols %<nop>USERSWEB%, %<nop>SYSTEMWEB% and %<nop>DOCWEB% can be used in the input to represent the web names set in $cfg{UsersWebName} and $cfg{SystemWebName}. For example:
2823| *Input* | *Return* |
2824| <tt>( '%<nop>USERSWEB%', 'Topic' )</tt> | <tt>( 'Main', 'Topic' ) </tt> |
2825| <tt>( '%<nop>SYSTEMWEB%', 'Topic' )</tt> | <tt>( 'System', 'Topic' ) </tt> |
2826| <tt>( '', '%<nop>DOCWEB%.Topic' )</tt> | <tt>( 'System', 'Topic' ) </tt> |
2827
2828=cut
2829
2830
# spent 1.85s (794ms+1.06) within Foswiki::Func::normalizeWebTopicName which was called 81336 times, avg 23µs/call: # 46040 times (445ms+527ms) by Foswiki::Store::SearchAlgorithms::Forking::search at line 101 of /var/www/foswiki11/lib/Foswiki/Store/SearchAlgorithms/Forking.pm, avg 21µs/call # 8845 times (127ms+139ms) by Foswiki::Search::InfoCache::addTopics at line 76 of /var/www/foswiki11/lib/Foswiki/Search/InfoCache.pm, avg 30µs/call # 8845 times (76.2ms+161ms) by Foswiki::Store::QueryAlgorithms::BruteForce::_webQuery at line 211 of /var/www/foswiki11/lib/Foswiki/Store/QueryAlgorithms/BruteForce.pm, avg 27µs/call # 8845 times (60.2ms+130ms) by Foswiki::Search::formatResults at line 779 of /var/www/foswiki11/lib/Foswiki/Search.pm, avg 22µs/call # 8760 times (85.6ms+101ms) by Foswiki::Search::InfoCache::addTopic at line 95 of /var/www/foswiki11/lib/Foswiki/Search/InfoCache.pm, avg 21µs/call # once (23µs+111µs) by Foswiki::Plugins::InterwikiPlugin::initPlugin at line 73 of /var/www/foswiki11/lib/Foswiki/Plugins/InterwikiPlugin.pm
sub normalizeWebTopicName {
2831
2832 #my( $web, $topic ) = @_;
28338133681.1ms8133672.2ms ASSERT($Foswiki::Plugins::SESSION) if DEBUG;
# spent 72.2ms making 81336 calls to Assert::ASSERTS_OFF, avg 888ns/call
283481336442ms81336986ms return $Foswiki::Plugins::SESSION->normalizeWebTopicName(@_);
# spent 986ms making 81336 calls to Foswiki::normalizeWebTopicName, avg 12µs/call
2835}
2836
2837=begin TML
2838
2839---+++ query($searchString, $topics, \%options ) -> iterator (resultset)
2840
2841Query the topic data in the specified webs. A programatic interface to SEARCH results.
2842
2843 * =$searchString= - the search string, as appropriate for the selected type
2844 * =$topics= - undef OR reference to a ResultSet, Iterator, or array containing the web.topics to be evaluated.
2845 if undef, then all the topics in the webs specified will be evaluated.
2846 * =\%option= - reference to an options hash
2847The =\%options= hash may contain the following options:
2848 * =type= - =regex=, =keyword=, =query=, ... defaults to =query=
2849 * =web= - The web/s to search in - string can have the same form as the =web= param of SEARCH (if not specified, defaults to BASEWEB)
2850 * =casesensitive= - false to ignore case (default true)
2851 * =files_without_match= - true to return files only (default false). If =files_without_match= is specified, it will return on the first match in each topic (i.e. it will return only one match per
2852 * topic, excludetopic and other params as per SEARCH
2853
2854To iterate over the returned topics use:
2855<verbatim>
2856 my $matches = Foswiki::Func::query( "Slimy Toad", undef,
2857 { web => 'Main,San*', casesensitive => 0, files_without_match => 0 } );
2858 while ($matches->hasNext) {
2859 my $webtopic = $matches->next;
2860 my ($web, $topic) = Foswiki::Func::normalizeWebTopicName('', $webtopic);
2861 ...etc
2862</verbatim>
2863
2864=cut
2865
2866sub query {
2867 my ( $searchString, $topics, $options ) = @_;
2868 ASSERT($Foswiki::Plugins::SESSION) if DEBUG;
2869
2870 my $inputTopicSet;
2871 if ($topics) {
2872 $inputTopicSet = new Foswiki::ListIterator($topics);
2873 }
2874 $options->{type} ||= 'query';
2875 my $query =
2876 $Foswiki::Plugins::SESSION->search->parseSearch( $searchString,
2877 $options );
2878
2879 return Foswiki::Meta::query( $query, $inputTopicSet, $options );
2880}
2881
2882=begin TML
2883
2884---+++ decodeFormatTokens($str) -> $unencodedString
2885
2886Foswiki has an informal standard set of tokens used in =format=
2887parameters that are used to block evaluation of paramater strings.
2888For example, if you were to write
2889
2890=%<nop>MYTAG{format="%<nop>WURBLE%"}%=
2891
2892then %<nop>WURBLE would be expanded *before* %<NOP>MYTAG is evaluated. To avoid
2893this Foswiki uses escapes in the format string. For example:
2894
2895=%<nop>MYTAG{format="$percentWURBLE$percent"}%=
2896
2897This lets you enter arbitrary strings into parameters without worrying that
2898Foswiki will expand them before your plugin gets a chance to deal with them
2899properly. Once you have processed your tag, you will want to expand these
2900tokens to their proper value. That's what this function does.
2901
2902The set of tokens that is expanded is described in System.FormatTokens.
2903
2904=cut
2905
2906sub decodeFormatTokens {
2907 return Foswiki::expandStandardEscapes(@_);
2908}
2909
2910=begin TML
2911
2912---+++ sanitizeAttachmentName($fname) -> ($fileName, $origName)
2913
2914Given a file path, sanitise it according to the rules for transforming
2915attachment names. Returns
2916the sanitised name together with the basename before sanitisation.
2917
2918Sanitation includes filtering illegal characters and mapping client
2919file names to legal server names.
2920
2921Avoid using this if you can; rewriting attachment names uses some very
2922nasty heuristics that cannot be changed because of compatibility issues.
2923It is much better use point-of-source validation to ensure only valid
2924attachment names are uploaded.
2925
2926=cut
2927
2928sub sanitizeAttachmentName {
2929 require Foswiki::Sandbox;
2930 return Foswiki::Sandbox::sanitizeAttachmentName(@_);
2931}
2932
2933=begin TML
2934
2935---+++ spaceOutWikiWord( $word, $sep ) -> $text
2936
2937Spaces out a wiki word by inserting a string (default: one space) between each word component.
2938With parameter $sep any string may be used as separator between the word components; if $sep is undefined it defaults to a space.
2939
2940=cut
2941
2942sub spaceOutWikiWord {
2943
2944 #my ( $word, $sep ) = @_;
2945 return Foswiki::spaceOutWikiWord(@_);
2946}
2947
2948=begin TML
2949
2950---+++ isTrue( $value, $default ) -> $boolean
2951
2952Returns 1 if =$value= is true, and 0 otherwise. "true" means set to
2953something with a Perl true value, with the special cases that "off",
2954"false" and "no" (case insensitive) are forced to false. Leading and
2955trailing spaces in =$value= are ignored.
2956
2957If the value is undef, then =$default= is returned. If =$default= is
2958not specified it is taken as 0.
2959
2960=cut
2961
2962
# spent 20µs (9+11) within Foswiki::Func::isTrue which was called 2 times, avg 10µs/call: # once (7µs+9µs) by Foswiki::Plugins::TablePlugin::Core::_parseAttributes at line 253 of /var/www/foswiki11/lib/Foswiki/Plugins/TablePlugin/Core.pm # once (3µs+2µs) by Foswiki::Plugins::TablePlugin::Core::_parseAttributes at line 301 of /var/www/foswiki11/lib/Foswiki/Plugins/TablePlugin/Core.pm
sub isTrue {
2963
2964 # my ( $value, $default ) = @_;
2965
296628µs211µs return Foswiki::isTrue(@_);
# spent 11µs making 2 calls to Foswiki::isTrue, avg 5µs/call
2967}
2968
2969=begin TML
2970
2971---+++ isValidWikiWord ( $text ) -> $boolean
2972
2973Check for a valid WikiWord or WikiName
2974 * =$text= - Word to test
2975
2976=cut
2977
2978sub isValidWikiWord {
2979 return Foswiki::isValidWikiWord(@_);
2980}
2981
2982=begin TML
2983
2984---+++ extractParameters($attr ) -> %params
2985
2986Extract all parameters from a variable string and returns a hash of parameters
2987 * =$attr= - Attribute string
2988Return: =%params= Hash containing all parameters. The nameless parameter is stored in key =_DEFAULT=
2989
2990 * Example:
2991 * Variable: =%<nop>TEST{ 'nameless' name1="val1" name2="val2" }%=
2992 * First extract text between ={...}= to get: ='nameless' name1="val1" name2="val2"=
2993 * Then call this on the text: <br />
2994 * params = Foswiki::Func::extractParameters( $text );=
2995 * The =%params= hash contains now: <br />
2996 =_DEFAULT => 'nameless'= <br />
2997 =name1 => "val1"= <br />
2998 =name2 => "val2"=
2999
3000=cut
3001
3002
# spent 149µs (30+120) within Foswiki::Func::extractParameters which was called 2 times, avg 75µs/call: # once (18µs+68µs) by Foswiki::Plugins::TablePlugin::_readPluginSettings at line 149 of /var/www/foswiki11/lib/Foswiki/Plugins/TablePlugin.pm # once (12µs+52µs) by Foswiki::Plugins::TablePlugin::_readPluginSettings at line 150 of /var/www/foswiki11/lib/Foswiki/Plugins/TablePlugin.pm
sub extractParameters {
300322µs my ($attr) = @_;
300421µs require Foswiki::Attrs;
300526µs2120µs my $params = new Foswiki::Attrs($attr);
# spent 120µs making 2 calls to Foswiki::Attrs::new, avg 60µs/call
3006
3007 # take out _RAW and _ERROR (compatibility)
300822µs delete $params->{_RAW};
30092500ns delete $params->{_ERROR};
3010217µs return %$params;
3011}
3012
3013=begin TML
3014
3015---+++ extractNameValuePair( $attr, $name ) -> $value
3016
3017Extract a named or unnamed value from a variable parameter string
3018- Note: | Function Foswiki::Func::extractParameters is more efficient for extracting several parameters
3019 * =$attr= - Attribute string
3020 * =$name= - Name, optional
3021Return: =$value= Extracted value
3022
3023 * Example:
3024 * Variable: =%<nop>TEST{ 'nameless' name1="val1" name2="val2" }%=
3025 * First extract text between ={...}= to get: ='nameless' name1="val1" name2="val2"=
3026 * Then call this on the text: <br />
3027 =my $noname = Foswiki::Func::extractNameValuePair( $text );= <br />
3028 =my $val1 = Foswiki::Func::extractNameValuePair( $text, "name1" );= <br />
3029 =my $val2 = Foswiki::Func::extractNameValuePair( $text, "name2" );=
3030
3031=cut
3032
3033sub extractNameValuePair {
3034 require Foswiki::Attrs;
3035 return Foswiki::Attrs::extractValue(@_);
3036}
3037
3038=begin TML
3039
3040---+++ sendEmail ( $text, $retries ) -> $error
3041
3042 * =$text= - text of the mail, including MIME headers
3043 * =$retries= - number of times to retry the send (default 1)
3044Send an e-mail specified as MIME format content. To specify MIME
3045format mails, you create a string that contains a set of header
3046lines that contain field definitions and a message body such as:
3047<verbatim>
3048To: liz@windsor.gov.uk
3049From: serf@hovel.net
3050CC: george@whitehouse.gov
3051Subject: Revolution
3052
3053Dear Liz,
3054
3055Please abolish the monarchy (with King George's permission, of course)
3056
3057Thanks,
3058
3059A. Peasant
3060</verbatim>
3061Leave a blank line between the last header field and the message body.
3062
3063=cut
3064
3065sub sendEmail {
3066
3067 #my( $text, $retries ) = @_;
3068 ASSERT($Foswiki::Plugins::SESSION) if DEBUG;
3069 return $Foswiki::Plugins::SESSION->net->sendEmail(@_);
3070}
3071
3072=begin TML
3073
3074---++ Logging
3075
3076=cut
3077
3078=begin TML
3079
3080---+++ writeEvent( $action, $extra )
3081
3082Log an event.
3083 * =$action= - name of the event (keep them unique!)
3084 * =$extra= - arbitrary extra information to add to the log.
3085You can enumerate the contents of the log using the =eachEventSince= function.
3086
3087*NOTE:* Older plugins may use =$Foswiki::cfg{LogFileName}=. These
3088plugins must be modified to use =writeEvent= and =eachEventSince= instead.
3089
3090To maintain compatibility with older Foswiki releases, you can write
3091conditional code as follows:
3092<verbatim>
3093if (defined &Foswiki::Func::writeEvent) {
3094 # use writeEvent and eachEventSince
3095} else {
3096 # old code using {LogFileName}
3097}
3098</verbatim>
3099
3100Note that the ability to read/write =$Foswiki::cfg{LogFileName}= is
3101maintained for compatibility but is *deprecated* (should not be used
3102in new code intended to work only with Foswiki 1.1 and later) and will
3103not work with any installation that stores logs in a database.
3104
3105=cut
3106
3107sub writeEvent {
3108 my ( $action, $extra ) = @_;
3109 ASSERT($Foswiki::Plugins::SESSION) if DEBUG;
3110 my $webTopic =
3111 $Foswiki::Plugins::SESSION->{webName} . '.'
3112 . $Foswiki::Plugins::SESSION->{topicName};
3113 return $Foswiki::Plugins::SESSION->logEvent( $action, $webTopic, $extra );
3114}
3115
3116=begin TML
3117
3118---+++ writeWarning( $text )
3119
3120Log a warning that may require admin intervention to the warnings log (=data/warn*.txt=)
3121 * =$text= - Text to write; timestamp gets added
3122
3123=cut
3124
3125sub writeWarning {
3126 ASSERT($Foswiki::Plugins::SESSION) if DEBUG;
3127 return $Foswiki::Plugins::SESSION->logger->log( 'warning',
3128 scalar( caller() ), @_ );
3129}
3130
3131=begin TML
3132
3133---+++ writeDebug( $text )
3134
3135Log debug message to the debug log
3136 * =$text= - Text to write; timestamp gets added
3137
3138=cut
3139
3140sub writeDebug {
3141
3142 # my( $text ) = @_;
3143 ASSERT($Foswiki::Plugins::SESSION) if DEBUG;
3144 return $Foswiki::Plugins::SESSION->logger->log( 'debug', @_ );
3145}
3146
3147=begin TML
3148
3149---+++ eachEventSince($time, $level) -> $iterator
3150 * =$time= - a time in the past (seconds since the epoch)
3151 * =$level= - log level to return events for.
3152
3153Get an iterator over the list of all the events at the given level
3154between =$time= and now. Events are written to the event log using
3155=writeEvent=. The Foswiki core will write other events that will
3156also be returned.
3157
3158If the chosen Logger does not support querying the logs, an empty
3159iterator will be returned. The supplied PlainFile and Compatibility loggers
3160will return events only if the log files have not been archived.
3161
3162Events are returned in *oldest-first* order.
3163
3164Each event is returned as a reference to an array. The elements are:
3165 1 date of the event (seconds since the epoch)
3166 1 login name of the user who triggered the event
3167 1 the event name (the $action passed to =writeEvent=)
3168 1 the Web.Topic that the event applied to
3169 1 Extras (the $extra passed to =writeEvent=)
3170 1 The IP address that was the source of the event (if known)
3171
3172Use the iterator like this:
3173<verbatim>
3174my $it = Foswiki::Func::eachEventSince(Foswiki::Time::parseTime("1 Apr 2010"));
3175while ($it->hasNext()) {
3176 my $entry = $it->next();
3177 my $date = $entry->[0];
3178 my $loginName = $entry->[1];
3179 ...
3180}
3181</verbatim>
3182
3183=cut
3184
3185sub eachEventSince {
3186 my $time = shift;
3187 return $Foswiki::Plugins::SESSION->logger->eachEventSince( $time, 'info' );
3188}
3189
3190=begin TML
3191
3192---++ Deprecated functions
3193
3194From time-to-time, the Foswiki developers will add new functions to the interface (either to =Foswiki::Func=, or new handlers). Sometimes these improvements mean that old functions have to be deprecated to keep the code manageable. When this happens, the deprecated functions will be supported in the interface for at least one more release, and probably longer, though this cannot be guaranteed.
3195
3196Updated plugins may still need to define deprecated handlers for compatibility with old Foswiki versions. In this case, the plugin package that defines old handlers can suppress the warnings in %<nop>FAILEDPLUGINS%.
3197
3198This is done by defining a map from the handler name to the =Foswiki::Plugins= version _in which the handler was first deprecated_. For example, if we need to define the =endRenderingHandler= for compatibility with =Foswiki::Plugins= versions before 1.1, we would add this to the plugin:
3199<verbatim>
3200package Foswiki::Plugins::SinkPlugin;
3201use vars qw( %FoswikiCompatibility );
3202$FoswikiCompatibility{endRenderingHandler} = 1.1;
3203</verbatim>
3204If the currently-running code version is 1.1 _or later_, then the _handler will not be called_ and _the warning will not be issued_. Wersions of =Foswiki::Plugins= before 1.1 will still call the handler as required.
3205
3206The following functions are retained for compatibility only. You should
3207stop using them as soon as possible.
3208
3209=cut
3210
3211=begin TML
3212
3213---+++ getRegularExpression( $name ) -> $expr
3214
3215*Deprecated* 28 Nov 2008 - use =$Foswiki::regex{...}= instead, it is directly
3216equivalent.
3217
3218See System.DevelopingPlugins for more information
3219
3220=cut
3221
3222
# spent 14µs within Foswiki::Func::getRegularExpression which was called 6 times, avg 2µs/call: # once (6µs+0s) by Foswiki::Plugins::FindElsewherePlugin::Core::_lazyInit at line 78 of /var/www/foswiki11/lib/Foswiki/Plugins/FindElsewherePlugin/Core.pm # once (2µs+0s) by Foswiki::Plugins::FindElsewherePlugin::Core::_lazyInit at line 84 of /var/www/foswiki11/lib/Foswiki/Plugins/FindElsewherePlugin/Core.pm # once (2µs+0s) by Foswiki::Plugins::FindElsewherePlugin::Core::_lazyInit at line 80 of /var/www/foswiki11/lib/Foswiki/Plugins/FindElsewherePlugin/Core.pm # once (2µs+0s) by Foswiki::Plugins::FindElsewherePlugin::Core::_lazyInit at line 86 of /var/www/foswiki11/lib/Foswiki/Plugins/FindElsewherePlugin/Core.pm # once (2µs+0s) by Foswiki::Plugins::FindElsewherePlugin::Core::_lazyInit at line 79 of /var/www/foswiki11/lib/Foswiki/Plugins/FindElsewherePlugin/Core.pm # once (1µs+0s) by Foswiki::Plugins::FindElsewherePlugin::Core::_lazyInit at line 85 of /var/www/foswiki11/lib/Foswiki/Plugins/FindElsewherePlugin/Core.pm
sub getRegularExpression {
322362µs my ($regexName) = @_;
3224623µs return $Foswiki::regex{$regexName};
3225}
3226
3227=begin TML
3228
3229---+++ getWikiToolName( ) -> $name
3230
3231*Deprecated* 28 Nov 2008 in Foswiki; use $Foswiki::cfg{WikiToolName} instead
3232
3233=cut
3234
3235sub getWikiToolName { return $Foswiki::cfg{WikiToolName}; }
3236
3237=begin TML
3238
3239---+++ getMainWebname( ) -> $name
3240
3241*Deprecated* 28 Nov 2008 in Foswiki; use $Foswiki::cfg{UsersWebName} instead
3242
3243=cut
3244
3245sub getMainWebname { return $Foswiki::cfg{UsersWebName}; }
3246
3247=begin TML
3248
3249---+++ getTwikiWebname( ) -> $name
3250
3251*Deprecated* 28 Nov 2008 in Foswiki; use $Foswiki::cfg{SystemWebName} instead
3252
3253=cut
3254
3255sub getTwikiWebname { return $Foswiki::cfg{SystemWebName}; }
3256
3257=begin TML
3258
3259---+++ getOopsUrl( $web, $topic, $template, $param1, $param2, $param3, $param4 ) -> $url
3260
3261Compose fully qualified 'oops' dialog URL
3262 * =$web= - Web name, e.g. ='Main'=. The current web is taken if empty
3263 * =$topic= - Topic name, e.g. ='WebNotify'=
3264 * =$template= - Oops template name, e.g. ='oopsmistake'=. The 'oops' is optional; 'mistake' will translate to 'oopsmistake'.
3265 * =$param1= ... =$param4= - Parameter values for %<nop>PARAM1% ... %<nop>PARAMn% variables in template, optional
3266Return: =$url= URL, e.g. ="http://example.com:80/cgi-bin/oops.pl/ Main/WebNotify?template=oopslocked&amp;param1=joe"=
3267
3268*Deprecated* 28 Nov 2008, the recommended approach is to throw an oops exception.
3269<verbatim>
3270 use Error qw( :try );
3271
3272 throw Foswiki::OopsException(
3273 'toestuckerror',
3274 web => $web,
3275 topic => $topic,
3276 params => [ 'I got my toe stuck' ]);
3277</verbatim>
3278(this example will use the =oopstoestuckerror= template.)
3279
3280If this is not possible (e.g. in a REST handler that does not trap the exception)
3281then you can use =getScriptUrl= instead:
3282<verbatim>
3283 my $url = Foswiki::Func::getScriptUrl($web, $topic, 'oops',
3284 template => 'oopstoestuckerror',
3285 param1 => 'I got my toe stuck');
3286 Foswiki::Func::redirectCgiQuery( undef, $url );
3287 return 0;
3288</verbatim>
3289
3290=cut
3291
3292sub getOopsUrl {
3293 my ( $web, $topic, $template, @params ) = @_;
3294
3295 my $n = 1;
3296 @params = map { 'param' . ( $n++ ) => $_ } @params;
3297 return getScriptUrl(
3298 $web, $topic, 'oops',
3299 template => $template,
3300 @params
3301 );
3302}
3303
3304=begin TML
3305
3306---+++ wikiToEmail( $wikiName ) -> $email
3307
3308 * =$wikiname= - wiki name of the user
3309Get the e-mail address(es) of the named user. If the user has multiple
3310e-mail addresses (for example, the user is a group), then the list will
3311be comma-separated.
3312
3313*Deprecated* 28 Nov 2008 in favour of wikinameToEmails, because this function only
3314returns a single email address, where a user may in fact have several.
3315
3316$wikiName may also be a login name.
3317
3318=cut
3319
3320sub wikiToEmail {
3321 my ($user) = @_;
3322 my @emails = wikinameToEmails($user);
3323 if ( scalar(@emails) ) {
3324 return $emails[0];
3325 }
3326 return '';
3327}
3328
3329=begin TML
3330
3331---+++ permissionsSet( $web ) -> $boolean
3332
3333Test if any access restrictions are set for this web, ignoring settings on
3334individual pages
3335 * =$web= - Web name, required, e.g. ='Sandbox'=
3336
3337*Deprecated* 28 Nov 2008 - use =getPreferencesValue= instead to determine
3338what permissions are set on the web, for example:
3339<verbatim>
3340foreach my $type (qw( ALLOW DENY )) {
3341 foreach my $action (qw( CHANGE VIEW )) {
3342 my $pref = $type . 'WEB' . $action;
3343 my $val = Foswiki::Func::getPreferencesValue( $pref, $web ) || '';
3344 if( $val =~ /\S/ ) {
3345 print "$pref is set to $val on $web\n";
3346 }
3347 }
3348}
3349</verbatim>
3350
3351=cut
3352
3353sub permissionsSet {
3354 my ($web) = @_;
3355
3356 foreach my $type (qw( ALLOW DENY )) {
3357 foreach my $action (qw( CHANGE VIEW RENAME )) {
3358 my $pref = $type . 'WEB' . $action;
3359 my $val = getPreferencesValue( $pref, $web ) || '';
3360 return 1 if ( $val =~ /\S/ );
3361 }
3362 }
3363
3364 return 0;
3365}
3366
3367=begin TML
3368
3369---+++ getPublicWebList( ) -> @webs
3370
3371*Deprecated* 28 Nov 2008 - use =getListOfWebs= instead.
3372
3373Get list of all public webs, e.g. all webs *and subwebs* that do not have the =NOSEARCHALL= flag set in the WebPreferences
3374
3375Return: =@webs= List of all public webs *and subwebs*
3376
3377=cut
3378
3379sub getPublicWebList {
3380 return getListOfWebs("user,public");
3381}
3382
3383=begin TML
3384
3385---+++ formatTime( $time, $format, $timezone ) -> $text
3386
3387*Deprecated* 28 Nov 2008 - use =Foswiki::Time::formatTime= instead (it has an identical interface).
3388
3389Format the time in seconds into the desired time string
3390 * =$time= - Time in epoch seconds
3391 * =$format= - Format type, optional. Default e.g. ='31 Dec 2002 - 19:30'=. Can be ='$iso'= (e.g. ='2002-12-31T19:30Z'=), ='$rcs'= (e.g. ='2001/12/31 23:59:59'=, ='$http'= for HTTP header format (e.g. ='Thu, 23 Jul 1998 07:21:56 GMT'=), or any string with tokens ='$seconds, $minutes, $hours, $day, $wday, $month, $mo, $year, $ye, $tz'= for seconds, minutes, hours, day of month, day of week, 3 letter month, 2 digit month, 4 digit year, 2 digit year, timezone string, respectively
3392 * =$timezone= - either not defined (uses the displaytime setting), 'gmtime', or 'servertime'
3393Return: =$text= Formatted time string
3394| Note: | if you used the removed formatGmTime, add a third parameter 'gmtime' |
3395
3396=cut
3397
3398sub formatTime {
3399
3400 # my ( $epSecs, $format, $timezone ) = @_;
3401 require Foswiki::Time;
3402 return Foswiki::Time::formatTime(@_);
3403}
3404
3405=begin TML
3406
3407---+++ formatGmTime( $time, $format ) -> $text
3408
3409*Deprecated* 28 Nov 2008 - use =Foswiki::Time::formatTime= instead.
3410
3411Format the time to GM time
3412 * =$time= - Time in epoc seconds
3413 * =$format= - Format type, optional. Default e.g. ='31 Dec 2002 - 19:30'=, can be ='iso'= (e.g. ='2002-12-31T19:30Z'=), ='rcs'= (e.g. ='2001/12/31 23:59:59'=, ='http'= for HTTP header format (e.g. ='Thu, 23 Jul 1998 07:21:56 GMT'=)
3414Return: =$text= Formatted time string
3415
3416=cut
3417
3418sub formatGmTime {
3419
3420 # my ( $epSecs, $format ) = @_;
3421 require Foswiki::Time;
3422 return Foswiki::Time::formatTime( @_, 'gmtime' );
3423}
3424
3425=begin TML
3426
3427---+++ getDataDir( ) -> $dir
3428
3429*Deprecated* 28 Nov 2008 - use the "Webs, Topics and Attachments" functions
3430to manipulate topics instead
3431
3432=cut
3433
3434sub getDataDir {
3435 return $Foswiki::cfg{DataDir};
3436}
3437
3438=begin TML
3439
3440---+++ getPubDir( ) -> $dir
3441
3442*Deprecated* 28 Nov 2008 - use the "Webs, Topics and Attachments" functions
3443to manipulate attachments instead
3444
3445=cut
3446
3447sub getPubDir { return $Foswiki::cfg{PubDir}; }
3448
3449=begin TML
3450
3451---+++ getCgiQuery( ) -> $query
3452
3453*Deprecated* 31 Mar 2009 - use =getRequestObject= instead if you can. Code
3454that is expected to run with pre-1.1 versions of Foswiki will still need to
3455use this method, as =getRequestObject= will not be available.
3456
3457=cut
3458
345924120µs24155µs
# spent 279µs (124+155) within Foswiki::Func::getCgiQuery which was called 24 times, avg 12µs/call: # 13 times (85µs+104µs) by Foswiki::Plugins::CommentPlugin::commonTagsHandler at line 30 of /var/www/foswiki11/lib/Foswiki/Plugins/CommentPlugin.pm, avg 15µs/call # 5 times (15µs+23µs) by Foswiki::Plugins::ChecklistPlugin::postRenderingHandler at line 1085 of /var/www/foswiki11/lib/Foswiki/Plugins/ChecklistPlugin.pm, avg 8µs/call # once (10µs+7µs) by Foswiki::Plugins::EditTablePlugin::initPlugin at line 46 of /var/www/foswiki11/lib/Foswiki/Plugins/EditTablePlugin.pm # once (3µs+5µs) by Foswiki::Plugins::TablePlugin::initPlugin at line 43 of /var/www/foswiki11/lib/Foswiki/Plugins/TablePlugin.pm # once (3µs+5µs) by Foswiki::Plugins::TablePlugin::Core::handler at line 1854 of /var/www/foswiki11/lib/Foswiki/Plugins/TablePlugin/Core.pm # once (3µs+5µs) by Foswiki::Plugins::TinyMCEPlugin::initPlugin at line 30 of /var/www/foswiki11/lib/Foswiki/Plugins/TinyMCEPlugin.pm # once (3µs+4µs) by Foswiki::Plugins::TablePlugin::Core::_parseAttributes at line 292 of /var/www/foswiki11/lib/Foswiki/Plugins/TablePlugin/Core.pm # once (2µs+3µs) by Foswiki::Plugins::WysiwygPlugin::beforeCommonTagsHandler at line 277 of /var/www/foswiki11/lib/Foswiki/Plugins/WysiwygPlugin.pm
sub getCgiQuery { return getRequestObject(); }
# spent 155µs making 24 calls to Foswiki::Func::getRequestObject, avg 6µs/call
3460
3461# Removed; it was never used
3462sub checkDependencies {
3463 die
3464"checkDependencies removed; contact plugin author or maintainer and tell them to use BuildContrib DEPENDENCIES instead";
3465}
3466
3467=begin TML
3468
3469---+++ readTopicText( $web, $topic, $rev, $ignorePermissions ) -> $text
3470
3471Read topic text, including meta data
3472 * =$web= - Web name, e.g. ='Main'=, or empty
3473 * =$topic= - Topic name, e.g. ='MyTopic'=, or ="Main.MyTopic"=
3474 * =$rev= - Topic revision to read, optional. Specify the minor part of the revision, e.g. ="5"=, not ="1.5"=; the top revision is returned if omitted or empty.
3475 * =$ignorePermissions= - Set to ="1"= if checkAccessPermission() is already performed and OK; an oops URL is returned if user has no permission
3476
3477Return: =$text= Topic text with embedded meta data; an oops URL for calling redirectCgiQuery() is returned in case of an error
3478
3479*Deprecated: 6 Aug 2009. Use =readTopic= instead.
3480This method returns meta-data embedded in the text. Plugins authors must be very careful to avoid damaging meta-data. Use readTopic instead, which is a lot safer and supports the full set of read options.
3481
3482=cut
3483
3484
# spent 9.53ms (86µs+9.44) within Foswiki::Func::readTopicText which was called 2 times, avg 4.76ms/call: # once (49µs+8.66ms) by Foswiki::Plugins::SmiliesPlugin::initPlugin at line 38 of /var/www/foswiki11/lib/Foswiki/Plugins/SmiliesPlugin.pm # once (37µs+778µs) by Foswiki::Plugins::InterwikiPlugin::initPlugin at line 87 of /var/www/foswiki11/lib/Foswiki/Plugins/InterwikiPlugin.pm
sub readTopicText {
348523µs my ( $web, $topic, $rev, $ignorePermissions ) = @_;
348622µs22µs ASSERT($Foswiki::Plugins::SESSION) if DEBUG;
# spent 2µs making 2 calls to Assert::ASSERTS_OFF, avg 950ns/call
3487
348821µs my $user;
34892600ns $user = $Foswiki::Plugins::SESSION->{user}
3490 unless defined($ignorePermissions);
3491
349228µs25.57ms my $topicObject =
# spent 5.57ms making 2 calls to Foswiki::Meta::load, avg 2.78ms/call
3493 Foswiki::Meta->load( $Foswiki::Plugins::SESSION, $web, $topic, $rev );
3494
34952700ns my $text;
349629µs23.87ms if ( $ignorePermissions
# spent 3.87ms making 2 calls to Foswiki::Meta::getEmbeddedStoreForm, avg 1.94ms/call
3497 || $topicObject->haveAccess( 'VIEW',
3498 $Foswiki::Plugins::SESSION->{user} ) )
3499 {
3500 $text = $topicObject->getEmbeddedStoreForm();
3501 }
3502 else {
3503 $text = getScriptUrl(
3504 $web, $topic, 'oops',
3505 template => 'oopsaccessdenied',
3506 def => 'topic_access',
3507 param1 => 'VIEW',
3508 param2 => $Foswiki::Meta::reason
3509 );
3510 }
3511
3512255µs return $text;
3513}
3514
3515=begin TML
3516
3517---+++ saveTopicText( $web, $topic, $text, $ignorePermissions, $dontNotify ) -> $oopsUrl
3518
3519Save topic text, typically obtained by readTopicText(). Topic data usually includes meta data; the file attachment meta data is replaced by the meta data from the topic file if it exists.
3520 * =$web= - Web name, e.g. ='Main'=, or empty
3521 * =$topic= - Topic name, e.g. ='MyTopic'=, or ="Main.MyTopic"=
3522 * =$text= - Topic text to save, assumed to include meta data
3523 * =$ignorePermissions= - Set to ="1"= if checkAccessPermission() is already performed and OK
3524 * =$dontNotify= - Set to ="1"= if not to notify users of the change
3525
3526*Deprecated* 6 Aug 2009 - use saveTopic instead.
3527=saveTopic= supports embedded meta-data in the saved text, and also
3528supports the full set of save options.
3529
3530Return: =$oopsUrl= Empty string if OK; the =$oopsUrl= for calling redirectCgiQuery() in case of error
3531
3532<verbatim>
3533my $text = Foswiki::Func::readTopicText( $web, $topic );
3534
3535# check for oops URL in case of error:
3536if( $text =~ /^http.*?\/oops/ ) {
3537 Foswiki::Func::redirectCgiQuery( $query, $text );
3538 return;
3539}
3540# do topic text manipulation like:
3541$text =~ s/old/new/g;
3542# do meta data manipulation like:
3543$text =~ s/(META\:FIELD.*?name\=\"TopicClassification\".*?value\=\")[^\"]*/$1BugResolved/;
3544$oopsUrl = Foswiki::Func::saveTopicText( $web, $topic, $text ); # save topic text
3545</verbatim>
3546
3547=cut
3548
3549sub saveTopicText {
3550 my ( $web, $topic, $text, $ignorePermissions, $dontNotify ) = @_;
3551 ASSERT($Foswiki::Plugins::SESSION) if DEBUG;
3552
3553 my $session = $Foswiki::Plugins::SESSION;
3554
3555 # extract meta data and merge old attachment meta data
3556 require Foswiki::Meta;
3557 my $topicObject = Foswiki::Meta->new( $session, $web, $topic );
3558 $topicObject->remove('FILEATTACHMENT');
3559
3560 my $oldMeta = Foswiki::Meta->load( $session, $web, $topic );
3561 $topicObject->copyFrom( $oldMeta, 'FILEATTACHMENT' );
3562
3563 my $outcome = '';
3564 unless ( $ignorePermissions || $topicObject->haveAccess('CHANGE') ) {
3565 my @caller = caller();
3566 return getScriptUrl(
3567 $web, $topic, 'oops',
3568 template => 'oopsattention',
3569 def => 'topic_access',
3570 param1 => ( $caller[0] || 'unknown' )
3571 );
3572 }
3573
3574 #see Tasks.Item11586 - saveTopicText is supposed to use the embedded meta
3575 $topicObject->setEmbeddedStoreForm($text);
3576
3577 try {
3578 $topicObject->save( minor => $dontNotify );
3579 }
3580 catch Error::Simple with {
3581 $outcome = getScriptUrl(
3582 $web, $topic, 'oops',
3583 template => 'oopsattention',
3584 def => 'save_error',
3585 param1 => shift->{-text}
3586 );
3587 };
3588 return $outcome;
3589}
3590
3591=begin TML
3592
3593---+++ addToHEAD( $id, $data, $requires )
3594
3595Adds =$data= to the HTML header (the &lt;head> tag).
3596
3597*Deprecated* 26 Mar 2010 - use =addZoZone('head', ...)=.
3598
3599%X% *Note:* Any calls using addToHEAD for javascript should be rewritten to use the
3600new =script= zone in addToZone as soon as possible.
3601
3602Rewrite:
3603<verbatim>
3604Foswiki::Func::addToHEAD("id", "<script>...</script>", "JQUERYPLUGIN");
3605</verbatim>
3606To:
3607<verbatim>
3608Foswiki::Func::addToZone("script", "id", "<script>...</script>", "JQUERYPLUGIN");
3609</verbatim>
3610
3611The reason is that all &lt;script> markup should be added to a dedicated zone, script,
3612and so any usage of ADDTOHEAD - which adds to the head zone - will be unable to
3613satisfy ordering requirements when the requirements exist in another zone ( script ).
3614
3615See Foswiki:Development/UpdatingExtensionsScriptZone for more details.
3616
3617=cut
3618
3619sub addToHEAD {
3620 $Foswiki::Plugins::SESSION->addToZone( 'head', @_ );
3621}
3622
3623=begin TML
3624
3625---+++ searchInWebContent($searchString, $web, \@topics, \%options ) -> reference to a hash - keys of which are topic names
3626
3627*Deprecated* 17 Oct 2010 - use =query( ...)=.
3628__WARNING: This function has been deprecated in foswiki 1.1.0 for scalability reasons__
3629
3630
3631Search for a string in the content of a web. The search is over all content, including meta-data.
3632Meta-data matches will be returned as formatted lines within the topic content (meta-data matches are returned as lines of the format %META:\w+{.*}%)
3633 * =$searchString= - the search string, in egrep format
3634 * =$web= - The web/s to search in - string can have the same form as the =web= param of SEARCH
3635 * =\@topics= - reference to a list of topics to search (if undef, then the store will search all topics in the specified web/webs.)
3636 * =\%option= - reference to an options hash
3637The =\%options= hash may contain the following options:
3638 * =type= - =regex=, =keyword=, =query= - defaults to =regex=
3639 * =casesensitive= - false to ignore case (default true)
3640 * =files_without_match= - true to return files only (default false). If =files_without_match= is specified, it will return on the first match in each topic (i.e. it will return only one match per topic, and will not return matching lines).
3641 * TODO: topic, excludetopic and other params as per SEARCH
3642
3643The return value is a reference to a hash which maps each matching topic
3644name to a list of the lines in that topic that matched the search,
3645as would be returned by 'grep'.
3646
3647To iterate over the returned topics use:
3648<verbatim>
3649 my $matches = Foswiki::Func::searchInWebContent( "Slimy Toad", $searchWeb, \@topics,
3650 { casesensitive => 0, files_without_match => 0 } );
3651 foreach my $topic (keys(%$matches)) {
3652 ...etc
3653</verbatim>
3654
3655
3656=cut
3657
3658sub searchInWebContent {
3659
3660 my ( $searchString, $webs, $topics, $options ) = @_;
3661 ASSERT($Foswiki::Plugins::SESSION) if DEBUG;
3662
3663 my $inputTopicSet = $topics;
3664 if ( $topics and ( ref($topics) eq 'ARRAY' ) ) {
3665 $inputTopicSet = new Foswiki::ListIterator($topics);
3666 }
3667 $options->{type} ||= 'regex';
3668 $options->{web} = $webs;
3669 my $query =
3670 $Foswiki::Plugins::SESSION->search->parseSearch( $searchString,
3671 $options );
3672
3673 my $itr = Foswiki::Meta::query( $query, $inputTopicSet, $options );
3674 my %matches;
3675 while ( $itr->hasNext ) {
3676 my $webtopic = $itr->next;
3677 my ( $web, $searchTopic ) =
3678 Foswiki::Func::normalizeWebTopicName( '', $webtopic );
3679 $matches{$searchTopic} = 1;
3680 }
3681 return \%matches;
3682}
3683
368412µs1;
3685
3686__END__