source: trunk/core/bin/configure @ 8044

Revision 8044, 27.6 KB checked in by CrawfordCurrie, 3 years ago (diff)

Item9257: improve doc of how the initial startup process works

  • Property svn:executable set to *
Line 
1#!/usr/bin/perl -wT
2# See bottom of file for license and copyright information
3
4=begin TML
5
6Configuration script for Foswiki. Once you have a basic webserver
7configuration that lets you access this script, the rest of the
8configuration process is done from here.
9
10The script works from the top down, by checking features of the
11environment before moving on. The sequence is:
12   1. Check the version of perl
13   2. Check we have the modules to run this script
14   3. Check the environment
15   4. Check we have the modules to load the rest of configure
16... and so on. At any stage, the script reports any errors in the
17best way it can given the environment established so far.
18When the basic checks are complete, the script moves into the
19real configuration steps; setting configuration variables.
20
21This phase of the configure environment follows a Model-View-
22Controller pattern.
23
24---++ Controller
25This script is the controller; it handles communication with the
26browser (and thus the user). Communication is very simple; this script
27is re-invoked with different 'action' parameters to determine what it does.
28
29---++ Model
30The Model consists of a simple node tree, where each node represents a
31structural element in the *presentation* of the configuration (this may
32not be consistent with the structure of $Foswiki:cfg, so beware). Each
33leaf node has an associated Type (in the Types subdirectory) that has
34collected model and view behaviours for the basic types.
35
36Class hierarchy
37  * Foswiki::Configure::Item
38     * Foswiki::Configure::Value - a leaf value
39     * Foswiki::Configure::Section - a running node
40        * Foswiki::Configure::Root - a root section
41        * Foswiki::Configure::Pluggable - a plug-in subsection
42           * Foswiki::Configure::Pluggables::FINDEXTENSIONS - etc
43        * Foswiki::Configure::Checkers::Introduction - should be a Pluggable
44        * Foswiki::Configure::Checkers::Welcome - should be a Pluggable
45        * Foswiki::Configure::Checkers::MSWin32 - should be a Pluggable
46The Model is independent of the language used to represent the
47configuration. There is one parser/generator provided, FoswikiCfg, but it
48would be trivial to add others.
49
50---++ View
51The View is a DOM document, generated as HTML by a set of UI classes,
52all subclasses of Foswiki::Configure::UI. The UI classes visit the
53model in order to generate the HTML.
54
55---+++ UIs
56Each class in the model (Root, Section, Value, Item) has a corresponding UI
57decorator object, which renders HTML for the model. There are also a
58number of bespoke UIs, some of which assist =configure= in the generation
59of full screens (Introduction, Welcome, AUTH, UPDATE, EXTEND, EXTENSIONS,
60UPDATE) and others which relate to the Pluggables (FINDEXTENSIONS, LANGUAGES,
61PLUGINS). The special UI CGISetup is a specialised Section focused on groping
62the CGI configuration. Several of the bespoke UIs (CGISetup, Introduction,
63Welcome) have corresponding Checkers, which act as placeholders in the
64model for these sections.
65
66Class hierarchy
67   * Foswiki::Configure::UI
68      * Foswiki::Configure::Checker
69         * Foswiki::Configure::Checkers::* - see below
70      * Foswiki::Configure::UIs::* - components used in building screens
71         * Foswiki::Configure::UIs::Item
72            * Foswiki::Configure::UIs::Section
73               * Foswiki::Configure::UIs::Root
74               * Foswiki::Configure::UIs::Introduction
75               * Foswiki::Configure::UIs::Welcome
76               * Foswiki::Configure::UIs::MSWin32
77               * Foswiki::Configure::UIs::* - other UIs for Pluggables and screens
78            * Foswiki::Configure::UIs::Value
79
80---+++ Checkers
81Checkers give checking and guessing support for configuration values. Checkers
82are all subclasses of Foswiki::Configure::Checker, and inhabit a class
83hierarchy under it that mirrors the organisation of configuration keys in
84Foswiki.spec.  Checkers include read-only checking UI used for checking
85environment sanity (BasicSanity)
86
87Note that when configure is run for the first time (before LocalSite.cfg
88has been created) then only the first section of Foswiki.spec is loaded,
89and thus checkers only for that subset will be created and run. This means
90that on some platforms, initial configuration is a two-phase process, as
91the initial path checks are performed on the first run, and only on the
92second run, when LocalSite.cfg exists, are the other checkers built and
93invoked. This needs improving on.
94
95---+++ Types
96Types provide some UI support in the form of type-specific prompters.
97This is really an abuse of the Model, but it saves creating
98decorator classes for all the Model types.
99
100HTML is generated for the model using Visitor pattern. Each node in the tree
101is visited in depth-first order.
102
103Class hierarchy
104   * Foswiki::Configure::Type - base
105      * Foswiki::Configure::Types::NUMBER - numerical type (perl float values)
106         * Foswiki::Configure::Types::OCTAL - octal (permissions)
107      * Foswiki::Configure::Types::BOOLEAN - boolean type
108         * Foswiki::Configure::Types::LANGUAGE
109      * Foswiki::Configure::Types::PERL - perl structure
110      * Foswiki::Configure::Types::SELECT - select from a list of values
111         * Foswiki::Configure::Types::SELECTCLASS - select a class from a path
112      * Foswiki::Configure::Types::STRING - string type
113         * Foswiki::Configure::Types::REGEX - regular expression
114         * Foswiki::Configure::Types::COMMAND - shell command
115         * Foswiki::Configure::Types::PASSWORD - hidden password
116         * Foswiki::Configure::Types::PATH - file path (/)
117         * Foswiki::Configure::Types::URL - absolute url path (/)
118         * Foswiki::Configure::Types::URLPATH - relative url path (/)
119      * Foswiki::Configure::Types::UNKNOWN - unknown type
120
121TODO:
122The type classes are the obvious place to attach client-side javascript
123validators, thus releasing the server-side checkers to consider the "deeper"
124issues.
125
126=cut
127
128use strict;
129use warnings;
130
131# This is absolutely essential for error reporting. We load it using
132# an eval so we can report the problem.
133eval "use CGI::Carp qw(fatalsToBrowser)";
134if ($@) {
135    print <<"REPORT";
136Content-type: text/plain
137
138Could not load CGI::Carp. Please install this module before continuing.
139It can be downloaded from http://www.cpan.org
140
141The error seen was:
142$@
143REPORT
144    exit 1;
145}
146
147###########################################################
148# VERY basic stuff required for configure to work. Any errors
149# during this phase will throw a die, which will be picked up
150# using CGI::Carp fatalsToBrowser
151
152# Warnings are fatal
153$SIG{'__WARN__'} = sub { die @_ };
154
155eval 'require 5.00503';
156die $@ if $@;
157
158# We warn against running Foswiki on an older Perl version then 5.8.4
159# but we will not let configure die in this situation. The user
160# may have updated many libraries and tweaked Foswiki so let us give
161# him a chance.
162my $perlversion = $];
163if ( $perlversion < 5.006 ) {
164    print STDERR <<HERE;
165Your perl version is older than 5.6.0.
166Foswiki has only been successfully tested on Perl 5.6.X and 5.8.X,
167and there have been reports that it does not run on 5.5.
168Running Foswiki with an older Perl version requires upgrading of modules and
169tweaking of the Foswiki code.
170HERE
171}
172
173# Get web server's user and group info
174use vars qw($WebServer_uid $WebServer_gid);
175$WebServer_uid = $WebServer_gid = '';
176
177eval { $WebServer_uid = getlogin() || getpwuid($>) || ''; };
178
179eval {
180    $WebServer_gid = join( ',', map { lc( getgrgid($_) ) } split( ' ', $( ) );
181};
182if ($@) {
183
184    # Try to use Cygwin's 'id' command - may be on the path, since Cygwin
185    # is probably installed to supply ls, egrep, etc - if it isn't, give
186    # up.
187    # Run command without stderr output, to avoid CGI giving error.
188    # Get names of primary and other groups.
189    $WebServer_gid = lc(qx(sh -c '( id -un ; id -gn) 2>/dev/null' 2>nul ));
190}
191
192my $localLibFailure;
193
194sub _loadBasicModule {
195    my ($module) = @_;
196
197    eval "use $module";
198    if ($@) {
199        my $reason = "Failed to load the perl module $module. The module ";
200
201        # See if we can find the .pm on @INC
202        my $foundAt = "could not be found. ";
203        my $modpath = $module;
204        if ( $modpath =~ /^([\w:]+)/ ) {
205            $modpath =~ s#::#/#g;
206            $modpath .= '.pm';
207            foreach my $path (@INC) {
208                if ( -e "$path/$modpath" ) {
209                    $foundAt = "was found at $path/$modpath";
210                    if ( !-r "$path/$modpath" ) {
211                        $foundAt .= ", but I don't have permission to read it.";
212                    }
213                    last;
214                }
215            }
216        }
217        $reason .= $foundAt;
218
219        $reason .= <<HERE;
220
221
222Please ensure that:
223   1 $module is installed,
224   2 that the module is available on the \@INC path,
225   3 that the webserver user ($WebServer_uid) has permission to read the $modpath file.
226HERE
227
228        $reason .= <<HERE;
229The detailed error seen was:
230$@
231HERE
232        if ($localLibFailure) {
233            $reason .= <<HERE;
234
235NOTE that I was unable to load LocalLib.cfg because of the following error:
236
237$localLibFailure
238HERE
239        }
240        die $reason;
241    }
242}
243
244foreach my $module ( 'FindBin', 'File::Spec', 'Config', 'CGI qw(:any)', ) {
245    _loadBasicModule($module);
246}
247
248# Capture DIE for stack *when debugging*
249#$SIG{__DIE__} = sub { Carp::confess( $_[0] || '' ) };
250
251###########################################################
252# Establish the path to the Foswiki library
253
254# Set the working dir to the bin dir
255no warnings;
256$FindBin::Bin =~ /^(.*)$/;
257use warnings;
258chdir($1);
259my @root = File::Spec->splitdir($1);
260pop(@root);
261my $scriptName = Foswiki::getScriptName();
262
263# Try to load the LocalLib.cfg optional overload
264
265use lib '.';
266eval 'require "setlib.cfg"';
267
268if ($@) {
269
270    # No joy. Remember the failure so we can report it later.
271    $localLibFailure = $@;
272
273    # Stick the root/lib on the path; there's a high probability we'll be
274    # able to find the bits of Foswiki::Configure that way. We will report
275    # the setlib error later.
276    unshift( @INC, File::Spec->catfile( @root, 'lib' ) );
277}
278
279our $time         = time();
280
281# Load all the bits of the configure module that we explicitly use
282# The loadBasicModule does some extra analysis on errors.
283foreach my $module (
284    'Cwd',                               'Data::Dumper',
285    'File::Copy',                        'File::Temp',
286    'Foswiki::Configure::Checker',       'Foswiki::Configure::Item',
287    'Foswiki::Configure::Load',          'Foswiki::Configure::Pluggable',
288    'Foswiki::Configure::Root',          'Foswiki::Configure::Section',
289    'Foswiki::Configure::Type',          'Foswiki::Configure::Types::BOOLEAN',
290    'Foswiki::Configure::Types::NUMBER', 'Foswiki::Configure::Types::SELECT',
291    'Foswiki::Configure::Types::STRING', 'Foswiki::Configure::FoswikiCfg',
292    'Foswiki::Configure::Util',          'Foswiki::Configure::UI',
293    'Foswiki::Configure::UIs::Section',  'Foswiki::Configure::Value',
294    'Foswiki::Configure::Valuer',        'Foswiki::Configure::GlobalControls',
295    'Foswiki::Configure::TemplateParser',
296  )
297{
298    _loadBasicModule($module);
299}
300
301$| = 1;    # no buffering on STDOUT
302
303###########################################################
304# From this point on we shouldn't have any more "fatal" (to configure)
305# errors, so we can report errors in the browser (i.e. without using die)
306
307# We are configuring $Foswiki::cfg, so we need to be in package Foswiki from
308# now on.
309package Foswiki;
310
311# We keep the actual config, and the default from Foswiki.spec, separate
312use vars qw( %cfg $defaultCfg );
313
314# Declared in Foswiki to support checkers
315use vars qw( $query );
316
317# 'constants' used in Foswiki.spec
318use vars qw( $TRUE $FALSE );
319$TRUE  = 1;
320$FALSE = 0;
321our $badLSC;
322
323# Remember what we detected previously, for use by Checkers
324if ( $scriptName =~ /(\.\w+)$/ ) {
325    $Foswiki::cfg{DETECTED}{ScriptExtension} = $1;
326}
327
328# duplicated here, should use the one in Util.pm
329sub getScriptName {
330    my @script = File::Spec->splitdir( $ENV{SCRIPT_NAME} || 'THISSCRIPT' );
331    my $scriptName = pop(@script);
332    $scriptName =~ s/.*[\/\\]//;    # Fix for Item3511, on Win XP
333    return $scriptName;
334}
335
336###########################################################
337# Grope the OS. This duplicates a bit of code in Foswiki.pm,
338# but it has to be duplicated because we don't want to deal
339# with loading Foswiki just yet.
340
341unless ( $Foswiki::cfg{DetailedOS} ) {
342    $Foswiki::cfg{DetailedOS} = $^O;
343    unless ( $Foswiki::cfg{DetailedOS} ) {
344        require Config;
345        $Foswiki::cfg{DetailedOS} = $Config::Config{osname};
346    }
347}
348unless ( $Foswiki::cfg{OS} ) {
349    if ( $Foswiki::cfg{DetailedOS} =~ /darwin/i ) {    # MacOS X
350        $Foswiki::cfg{OS} = 'UNIX';
351    }
352    elsif ( $Foswiki::cfg{DetailedOS} =~ /Win/i ) {
353        $Foswiki::cfg{OS} = 'WINDOWS';
354    }
355    elsif ( $Foswiki::cfg{DetailedOS} =~ /vms/i ) {
356        $Foswiki::cfg{OS} = 'VMS';
357    }
358    elsif ( $Foswiki::cfg{DetailedOS} =~ /bsdos/i ) {
359        $Foswiki::cfg{OS} = 'UNIX';
360    }
361    elsif ( $Foswiki::cfg{DetailedOS} =~ /dos/i ) {
362        $Foswiki::cfg{OS} = 'DOS';
363    }
364    elsif ( $Foswiki::cfg{DetailedOS} =~ /^MacOS$/i ) {    # MacOS 9 or earlier
365        $Foswiki::cfg{OS} = 'MACINTOSH';
366    }
367    elsif ( $Foswiki::cfg{DetailedOS} =~ /os2/i ) {
368        $Foswiki::cfg{OS} = 'OS2';
369    }
370    else {
371        $Foswiki::cfg{OS} = 'UNIX';
372    }
373}
374
375our $query = new CGI;
376
377my $url = $query->url();
378my $action = $query->param('action') || 'Configure';
379
380our $DEFAULT_FIELD_WIDTH_NO_CSS = '40';
381
382# Handle serving an resource embedded in the configure page, before generating
383# any other output
384if ( $action eq 'resource' ) {
385    my $resource = $query->param('resource');
386    $resource =~ /^([-\w]+\.\w+)$/;    # filter-in and untaint
387    $resource = $1;
388    if ( defined($resource) ) {
389
390        #ignore $query->param('type') and set it using the extension
391        my $type = 'image/gif';
392        if ( $resource =~ /\.ico$/ ) {
393            $type = 'resource/x-icon';
394        }
395        elsif ( $resource =~ /\.js$/ ) {
396            $type = 'text/javascript';
397        }
398
399        my $parser = Foswiki::Configure::TemplateParser->new;
400        my $text = $parser->getResource($resource);
401
402        # SMELL: this call is correct, but causes a perl error
403        # on some versions of CGI.pm
404        # print $query->header(-type => $query->param('type'));
405        # So use this instead:
406        print 'Content-type: ' . $type . "\n\n";
407        print $text;
408    }
409    exit 0;
410}
411
412sub log {
413    my ($message) = @_;
414
415    $message ||= '';
416    my $log = $Foswiki::cfg{DebugFileName} || 'ConfigureError.log';
417    my $file;
418    if ( open( $file, '>>', $log ) ) {
419        print $file "$message\n";
420        close($file);
421    }
422}
423
424print $query->header('text/html');
425_dispatchContents();
426
427###########################################################
428# End of the main program; the rest is all subs
429
430sub _dispatchContents {
431    my $stub    = new Foswiki::Configure::Item();
432
433    # This call will define $Foswiki::defaultCfg by loading .spec files
434    my $sanityUI = Foswiki::Configure::UI::loadChecker( 'BasicSanity', $stub );
435
436    # Perform the check
437    my $sanityStatement = $sanityUI->check();
438    $badLSC = $sanityUI->lscIsBad();
439
440    # This is the dispatcher; $action is the name of the action to perform,
441    # this is concatenated to _action to determine the name of the procedure.
442    # Dispatcher methods return a boolean to indicate whether to generate a
443    # link back to the main page at the end.
444    if ( $sanityUI->insane() || $query->param('abort') ) {
445        print $sanityStatement;
446    }
447    else {
448
449        $action =~ s/\W//g;
450        my $method = '_action' . $action;
451
452        die "Undefined action $action" unless defined(&$method);
453
454        no strict 'refs';
455        &$method();
456        use strict 'refs';
457    }
458}
459
460sub _checkLoadUI {
461    my ( $uiname, $root ) = @_;
462    my $ui = Foswiki::Configure::UI::loadUI( $uiname, $root );
463    unless ($ui) {
464        print "Could not load $uiname UI. Error was: <pre>$@</pre>";
465        if ( $@ =~ /Can't locate (\S+)/ ) {
466            print <<HERE
467You may be able to correct this error by installing the missing $1 module.
468HERE
469        }
470    }
471    return $ui;
472}
473
474# Action invoked by 'Next' button on the main screen
475sub _actionSavechanges {
476
477    my ( $authorised, $messageType ) = Foswiki::Configure::UI::authorised();
478    if ( !$authorised ) {
479        _screenAuthorize($messageType);
480    }
481    else {
482        _screenFeedback($messageType);
483    }
484}
485
486# Screen that prompts for a password
487sub _screenAuthorize {
488    my ($messageType) = @_;
489    my $contents = '';
490    my $valuer =
491      new Foswiki::Configure::Valuer( $Foswiki::defaultCfg, \%Foswiki::cfg );
492    my %updated;
493    my $modified = $valuer->loadCGIParams( $Foswiki::query, \%updated );
494    my $changesList = ();
495    foreach my $key ( sort keys %updated ) {
496        my $valueString = $query->param($key);
497        push( @{$changesList}, { key => $key, value => $valueString } );
498    }
499
500    # create the root of the UI
501    my $root = new Foswiki::Configure::Root();
502    my $ui;
503    my @items       = ();
504    my $params      = '';
505    my $hasPassword = ( $Foswiki::cfg{Password} ne '' ) || 0;
506
507    @items = sort keys %updated if $modified;
508
509    $ui = _checkLoadUI( 'AUTH', $root );
510    return '' unless $ui;
511    $params = join( "\n", $ui->params() );
512
513    my $contentTemplate =
514      Foswiki::Configure::UI::getTemplateParser()->readTemplate('authorize');
515    my $changePassword = $Foswiki::query->param('changePassword') || undef;
516    Foswiki::Configure::UI::getTemplateParser()->parse(
517        $contentTemplate,
518        {
519            'main'           => $contents,
520            'hasPassword'    => $hasPassword,
521            'modifiedCount'  => $modified,
522            'items'          => \@items,
523            'changesList'    => $changesList,
524            'params'         => $params,
525            'messageType'    => $messageType,
526            'formAction'     => $scriptName,
527            'configureUrl'   => $url,
528            'changePassword' => $changePassword,
529        }
530    );
531
532    my $html =
533      Foswiki::Configure::UI::getTemplateParser()->readTemplate('pagebegin');
534    $html .= $contentTemplate;
535    $html .=
536      Foswiki::Configure::UI::getTemplateParser()->readTemplate('pageend');
537    Foswiki::Configure::UI::getTemplateParser()->parse(
538        $html,
539        {
540            'time'       => $time,
541            'formAction' => $scriptName,
542        }
543    );
544
545    Foswiki::Configure::UI::getTemplateParser()->cleanupTemplateResidues(
546        $html);
547    print $html;
548}
549
550# After authentication, the screen that shows the changes.
551sub _screenFeedback {
552    my ($messageType) = @_;
553    my $valuer =
554      new Foswiki::Configure::Valuer( $Foswiki::defaultCfg, \%Foswiki::cfg );
555    my %updated;
556    my $modified = $valuer->loadCGIParams( $Foswiki::query, \%updated );
557
558    # create the root of the UI
559    my $root = new Foswiki::Configure::Root();
560
561    # Load the specs from the .spec files and generate the UI template
562    Foswiki::Configure::FoswikiCfg::load( $root, 1 );
563
564    my $ui = _checkLoadUI( 'UPDATE', $root );
565    return '' unless $ui;
566
567    $ui->commitChanges( $root, $valuer, \%updated );
568
569    undef $ui;
570
571    # SMELL: why is this list built again? It's already been built
572    # once in commitChanges()
573    my $changesList = ();
574    foreach my $key ( sort keys %updated ) {
575        my $valueString = $query->param($key);
576        push( @{$changesList}, { key => $key, value => $valueString } );
577    }
578
579    my $contentTemplate =
580      Foswiki::Configure::UI::getTemplateParser()->readTemplate('feedback');
581    Foswiki::Configure::UI::getTemplateParser()->parse(
582        $contentTemplate,
583        {
584            'modifiedCount' => scalar keys %updated,
585            'changesList'   => $changesList,
586            'formAction'    => $scriptName,
587            'messageType'   => $messageType,
588        }
589    );
590
591    Foswiki::Configure::UI::getTemplateParser()->cleanupTemplateResidues(
592        $contentTemplate);
593
594    # If this pass created the LocalSite.cfg, need to rerun the sanity check
595    # to re-establish that the configuration is valid
596    if ( $badLSC ) {
597        my $stub    = new Foswiki::Configure::Item();
598        # This call will define $Foswiki::defaultCfg by loading .spec files
599        my $sanityUI = Foswiki::Configure::UI::loadChecker(
600            'BasicSanity', $stub );
601
602        my $sanityStatement = $sanityUI->check();
603        $badLSC = $sanityUI->lscIsBad();
604    }
605
606    # Pass control to the mainline configure screen, passing along the
607    # results of the save
608    _actionConfigure($contentTemplate);
609}
610
611# Invoked by "find more extensions" button in the Extensions section
612sub _actionFindMoreExtensions {
613    my $root = new Foswiki::Configure::Root();
614
615    my $ui = _checkLoadUI( 'EXTENSIONS', $root );
616    return unless $ui;
617
618    my ( $consultedLocations, $table, $errors, $installedCount, $allCount ) =
619      $ui->getExtensions();
620
621    my @script     = File::Spec->splitdir( $ENV{SCRIPT_NAME} );
622    my $scriptName = pop(@script);
623    $scriptName =~ s/.*[\/\\]//;               # Fix for Item3511, on Win XP
624
625    my $contentTemplate =
626      Foswiki::Configure::UI::getTemplateParser()->readTemplate('extensions');
627    Foswiki::Configure::UI::getTemplateParser()->parse(
628        $contentTemplate,
629        {
630            'formAction'         => $scriptName,
631            'table'              => $table,
632            'errors'             => $errors,
633            'consultedLocations' => $consultedLocations,
634            'installedCount'     => $installedCount,
635            'allCount'           => $allCount,
636        }
637    );
638
639    my $html =
640      Foswiki::Configure::UI::getTemplateParser()->readTemplate('pagebegin');
641    $html .= $contentTemplate;
642    $html .=
643      Foswiki::Configure::UI::getTemplateParser()->readTemplate('pageend');
644
645    Foswiki::Configure::UI::getTemplateParser()->parse(
646        $html,
647        {
648            'time'       => '',
649            'formAction' => $scriptName,
650        }
651    );
652
653    Foswiki::Configure::UI::getTemplateParser()->cleanupTemplateResidues(
654        $html);
655    print $html;
656}
657
658# Invoked when extensions are to be (un)installed
659sub _actionManageExtensions {
660
661    my $html =
662      Foswiki::Configure::UI::getTemplateParser()->readTemplate('pagebegin');
663    Foswiki::Configure::UI::getTemplateParser()->cleanupTemplateResidues(
664        $html);
665    print $html;
666
667    my $root = new Foswiki::Configure::Root();
668    my $ui;
669    if ( !Foswiki::Configure::UI::authorised() ) {
670        $ui = _checkLoadUI( 'AUTH', $root );
671        return 1 unless $ui;
672# SMELL: this doesn't work - should invoke _screenAuthorize, surely?
673        print $ui->ui( 0, 'Install ' . ( $query->param('extension') || '' ) );
674    }
675    else {
676        $ui = _checkLoadUI( 'EXTEND', $root );
677        return 1 unless $ui;
678        # Warning: the 'install' method uses print for rapid feedback
679        print $ui->install();
680    }
681
682    $html =
683      Foswiki::Configure::UI::getTemplateParser()->readTemplate('installed');
684    $html .=
685      Foswiki::Configure::UI::getTemplateParser()->readTemplate('pageend');
686
687    my $frontpageUrl =
688"$Foswiki::cfg{DefaultUrlHost}$Foswiki::cfg{ScriptUrlPath}/view$Foswiki::cfg{ScriptSuffix}/";
689    Foswiki::Configure::UI::getTemplateParser()->parse(
690        $html,
691        {
692            'frontpageUrl'  => $frontpageUrl,
693            'configureUrl'  => $url,
694        }
695    );
696
697    Foswiki::Configure::UI::getTemplateParser()->cleanupTemplateResidues(
698        $html);
699    print $html;
700}
701
702# This is the default screen
703sub _actionConfigure {
704
705    # If coming from the save action, pick up the messages
706    my $saveMsgs = shift;
707
708    my $contents    = '';
709    my $isFirstTime = $badLSC;
710    #allow debugging of checker's guesses by showing the entire UI
711    $isFirstTime = 0 if ($query->param('DEBUG'));
712
713    Foswiki::Configure::UI::reset($isFirstTime);
714
715    my $valuer =
716      new Foswiki::Configure::Valuer( $Foswiki::defaultCfg, \%Foswiki::cfg );
717
718    # This is the root of the model
719    my $root = new Foswiki::Configure::Root();
720
721    # Load special sections used as placeholders
722
723    my $intro = 'Foswiki::Configure::Checkers::'
724      .($isFirstTime ? 'Welcome' : 'Introduction');
725    eval "require $intro";
726    Carp::confess $@ if $@;
727
728    my $intro_checker = $intro->new($root);
729    $root->addChild($intro_checker);
730
731    my $oscfg = $Config::Config{osname};
732    if ($oscfg) {
733        # See if this platform has special detection or checking requirements
734        my $osospecial = "Foswiki::Configure::Checkers::$oscfg";
735        eval "require $osospecial";
736        unless ($@) {
737            my $os_checker = $osospecial->new($root);
738            $root->addChild($os_checker) if $os_checker;
739        }
740    }
741
742    my $cgienv = 'Foswiki::Configure::Checkers::CGISetup';
743    eval "require $cgienv";
744    Carp::confess $@ if $@;
745    my $cgi_checker = $cgienv->new($root);
746    $root->addChild($cgi_checker);
747
748    # Load the config structures.
749    # If $isFirstTime is true, only Foswiki.spec will be loaded
750    # (extension Config.spec files will *not* be loaded) and
751    # only the first section of Foswiki.spec will be processed
752    # i.e. all other sections will be skipped.
753    Foswiki::Configure::FoswikiCfg::load( $root, !$isFirstTime );
754
755    # Now generate the UI
756
757    # Load the UI for the root; this UI is simply a visitor over
758    # the model
759    my $ui = _checkLoadUI( 'Root', $root );
760    return '' unless $ui;
761
762    # Set the save messages into the introduction panel if any.
763    $ui->lastSave($saveMsgs) if ($saveMsgs);
764
765    # Visit the model and generate
766    $ui->{controls} = new Foswiki::Configure::GlobalControls();
767    $contents .= $ui->createUI( $root, $valuer );
768
769    my $showSanityStatement =
770      ( !$isFirstTime && !$Foswiki::query->auth_type() ) ? 1 : undef;
771
772    my $html =
773      Foswiki::Configure::UI::getTemplateParser()->readTemplate('pagebegin');
774    if ($showSanityStatement) {
775        $html .=
776          Foswiki::Configure::UI::getTemplateParser()->readTemplate('sanity');
777    }
778    $html .= $contents;
779    $html .=
780      Foswiki::Configure::UI::getTemplateParser()->readTemplate('pageend');
781    Foswiki::Configure::UI::getTemplateParser()->parse(
782        $html,
783        {
784            'time' => $time,     # use time to make sure we never allow cacheing
785            'formAction'          => $scriptName,
786        }
787    );
788
789    Foswiki::Configure::UI::getTemplateParser()->cleanupTemplateResidues(
790        $html);
791    print $html;
792}
793
7941;
795__END__
796Foswiki - The Free and Open Source Wiki, http://foswiki.org/
797
798Copyright (C) 2008-2010 Foswiki Contributors. Foswiki Contributors
799are listed in the AUTHORS file in the root of this distribution.
800NOTE: Please extend that file, not this notice.
801
802Additional copyrights apply to some or all of the code in this
803file as follows:
804
805Copyright (C) 2000-2007 TWiki Contributors. All Rights Reserved.
806
807This program is free software; you can redistribute it and/or
808modify it under the terms of the GNU General Public License
809as published by the Free Software Foundation; either version 2
810of the License, or (at your option) any later version. For
811more details read LICENSE in the root of this distribution.
812
813This program is distributed in the hope that it will be useful,
814but WITHOUT ANY WARRANTY; without even the implied warranty of
815MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
816
817As per the GPL, removal of this notice is prohibited.
Note: See TracBrowser for help on using the repository browser.