1
# See bottom of file for license and copyright information
5
---+ package Foswiki::Configure::Load
9
This module consists of just a single subroutine =readConfig=. It allows to
10
safely modify configuration variables _for one single run_ without affecting
11
normal Foswiki operation.
15
package Foswiki::Configure::Load;
21
---++ StaticMethod readConfig()
23
In normal Foswiki operations as a web server this routine is called by the
24
=BEGIN= block of =Foswiki.pm=. However, when benchmarking/debugging it can be
25
replaced by custom code which sets the configuration hash. To prevent us from
26
overriding the custom code again, we use an "unconfigurable" key
27
=$cfg{ConfigurationFinished}= as an indicator.
29
Note that this method is called by Foswiki and configure, and *only* reads
30
Foswiki.spec= to get defaults. Other spec files (those for extensions) are
33
The assumption is that =configure= will be run when an extension is installed,
34
and that will add the config values to LocalSite.cfg, so no defaults are
35
needed. Foswiki.spec is still read because so much of the core code doesn't
36
provide defaults, and it would be silly to have them in two places anyway.
41
return if $Foswiki::cfg{ConfigurationFinished};
44
unless ( do 'Foswiki.spec' ) {
46
Content-type: text/plain
48
Perl error when reading Foswiki.spec: $@
49
Please inform the site admin.
55
unless ( do 'LocalSite.cfg' ) {
57
Content-type: text/plain
59
Perl error when reading LocalSite.cfg: $@
60
Please inform the site admin.
65
# If we got this far without definitions for key variables, then
66
# we need to default them. otherwise we get peppered with
67
# 'uninitialised variable' alerts later.
69
foreach my $var qw( DataDir DefaultUrlHost PubUrlPath WorkingDir
70
PubDir TemplateDir ScriptUrlPath LocalesDir ) {
72
# We can't do this, because it prevents Foswiki being run without
73
# a LocalSite.cfg, which we don't want
74
# die "$var must be defined in LocalSite.cfg"
75
# unless( defined $Foswiki::cfg{$var} );
76
$Foswiki::cfg{$var} = 'NOT SET' unless defined $Foswiki::cfg{$var};
79
# Expand references to $Foswiki::cfg vars embedded in the values of
80
# other $Foswiki::cfg vars.
81
expand( \%Foswiki::cfg );
83
$Foswiki::cfg{ConfigurationFinished} = 1;
85
# Alias TWiki cfg to Foswiki cfg for plugins and contribs
86
*{'TWiki::cfg'} = *{'Foswiki::cfg'};
92
foreach ( values %$hash ) {
94
if ( ref($_) eq 'HASH' ) {
98
s/(\$Foswiki::cfg{[[A-Za-z0-9{}]+})/eval $1||'undef'/ge;
105
---++ StaticMethod expandValue($string) -> $boolean
107
Expands references to Foswiki configuration items which occur in the
108
value of other configuration items. Use expand($hashref) if the item
109
is not a plain scalar.
111
Happens to return true if something has been expanded, though I don't
112
know whether you would want that. The replacement is done in-place,
117
$_[0] =~ s/(\$Foswiki::cfg{[[A-Za-z0-9{}]+})/eval $1||'undef'/ge;
122
---++ StaticMethod readDefaults() -> \@errors
124
This is only called by =configure= to initialise the Foswiki config hash with
125
default values from the .spec files.
127
Normally all configuration values come from LocalSite.cfg. However when
128
=configure= runs it has to get default values for config vars that have not
129
yet been saved to =LocalSite.cfg=.
131
Returns a reference to a list of the errors it saw.
133
SEE ALSO: Foswiki::Configure::FoswikiCfg::load
143
$read{'Foswiki.spec'} = $INC{'Foswiki.spec'};
145
push( @errors, $@ ) if ($@);
146
foreach my $dir (@INC) {
147
_loadDefaultsFrom( "$dir/Foswiki/Plugins", $root, \%read, \@errors );
148
_loadDefaultsFrom( "$dir/Foswiki/Contrib", $root, \%read, \@errors );
149
_loadDefaultsFrom( "$dir/TWiki/Plugins", $root, \%read, \@errors );
150
_loadDefaultsFrom( "$dir/TWiki/Contrib", $root, \%read, \@errors );
152
if ( defined %TWiki::cfg ) {
154
# We had some TWiki plugins, need to map their config to Foswiki
157
# Merges the keys in the right hashref to the ones in the left hashref
158
my ( $left, $right, $errors ) = @_;
159
while ( my ( $key, $value ) = each %$right ) {
160
if ( exists $left->{$key} ) {
161
if ( ref($value) ne ref( $left->{$key} ) ) {
163
'Trying to overwrite $Foswiki::cfg{'
165
. '} with its $TWiki::cfg version ('
168
elsif ( ref($value) eq 'SCALAR' ) {
169
$left->{$key} = $value;
171
elsif ( ref($value) eq 'HASH' ) {
173
mergeHash( $left->{$key}, $value, $errors );
175
elsif ( ref($value) eq 'ARRAY' ) {
177
# It's an array. try to be smart
178
# SMELL: Ideally, it should keep order too
179
foreach my $item (@$value) {
180
unless ( grep /^$item$/, @{ $left->{$key} } ) {
182
# The item isn't in the current list, add it at the end
183
unshift @{ $left->{$key} }, $item;
189
# It's something else (GLOB, coderef, ...)
193
. '} is a reference to a'
195
. '. No idea how to merge that, sorry.';
200
# We don't already have such a key in the Foswiki scope
201
$left->{$key} = $value;
206
mergeHash \%Foswiki::cfg, \%TWiki::cfg, \@errors;
207
} # define %TWiki::cfg
212
sub _loadDefaultsFrom {
213
my ( $dir, $root, $read, $errors ) = @_;
215
return unless opendir( D, $dir );
216
foreach my $extension ( grep { !/^\./ } readdir D ) {
217
$extension =~ /(.*)/;
218
$extension = $1; # untaint
219
next if $read->{$extension};
220
my $file = "$dir/$extension/Config.spec";
221
next unless -e $file;
223
push( @$errors, $@ ) if ($@);
224
$read->{$extension} = $file;
231
# Module of Foswiki - The Free and Open Source Wiki, http://foswiki.org/
233
# Copyright (C) 2008 Foswiki Contributors. Foswiki Contributors
234
# are listed in the AUTHORS file in the root of this distribution.
235
# NOTE: Please extend that file, not this notice.
237
# Additional copyrights apply to some or all of the code in this
240
# Copyright (C) 1999-2006 TWiki Contributors. All Rights Reserved.
241
# TWiki Contributors are listed in the AUTHORS file in the root of
242
# this distribution. NOTE: Please extend that file, not this notice.
244
# This program is free software; you can redistribute it and/or
245
# modify it under the terms of the GNU General Public License
246
# as published by the Free Software Foundation; either version 2
247
# of the License, or (at your option) any later version. For
248
# more details read LICENSE in the root of this distribution.
250
# This program is distributed in the hope that it will be useful,
251
# but WITHOUT ANY WARRANTY; without even the implied warranty of
252
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
254
# As per the GPL, removal of this notice is prohibited.