← Index
NYTProf Performance Profile   « line view »
For ./view
  Run on Fri Jul 31 18:42:36 2015
Reported on Fri Jul 31 18:48:14 2015

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