import rt 3.8.7
[freeside.git] / rt / lib / RT / Installer.pm
diff --git a/rt/lib/RT/Installer.pm b/rt/lib/RT/Installer.pm
new file mode 100644 (file)
index 0000000..2cc5ba9
--- /dev/null
@@ -0,0 +1,340 @@
+# BEGIN BPS TAGGED BLOCK {{{
+# 
+# COPYRIGHT:
+# 
+# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC
+#                                          <jesse@bestpractical.com>
+# 
+# (Except where explicitly superseded by other copyright notices)
+# 
+# 
+# LICENSE:
+# 
+# This work is made available to you under the terms of Version 2 of
+# the GNU General Public License. A copy of that license should have
+# been provided with this software, but in any event can be snarfed
+# from www.gnu.org.
+# 
+# This work is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 or visit their web page on the internet at
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+# 
+# 
+# CONTRIBUTION SUBMISSION POLICY:
+# 
+# (The following paragraph is not intended to limit the rights granted
+# to you to modify and distribute this software under the terms of
+# the GNU General Public License and is only of importance to you if
+# you choose to contribute your changes and enhancements to the
+# community by submitting them to Best Practical Solutions, LLC.)
+# 
+# By intentionally submitting any modifications, corrections or
+# derivatives to this work, or any other work intended for use with
+# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+# you are the copyright holder for those contributions and you grant
+# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+# royalty-free, perpetual, license to use, copy, create derivative
+# works based on those contributions, and sublicense and distribute
+# those contributions and any derivatives thereof.
+# 
+# END BPS TAGGED BLOCK }}}
+
+package RT::Installer;
+use strict;
+use warnings;
+
+require UNIVERSAL::require;
+my %Meta = (
+    DatabaseType => {
+        Widget          => '/Widgets/Form/Select',
+        WidgetArguments => {
+            Description => 'Database type',    # loc
+            Values      => [
+                grep {
+                    my $m = 'DBD::' . $_;
+                    $m->require ? 1 : 0
+                  } qw/mysql Pg SQLite Oracle/
+            ],
+            ValuesLabel => {
+                mysql  => 'MySQL',             #loc
+                Pg     => 'PostgreSQL',        #loc
+                SQLite => 'SQLite',            #loc
+                Oracle => 'Oracle',            #loc
+            },
+        },
+    },
+    DatabaseHost => {
+        Widget          => '/Widgets/Form/String',
+        WidgetArguments => {
+            Description => 'Database host', #loc
+            Default => 1,
+            DefaultLabel => "Keep 'localhost' if you're not sure. Leave blank to connect locally over a socket", #loc
+            Hints => "The domain name of your database server (like 'db.example.com').",       #loc
+        },
+    },
+    DatabasePort => {
+        Widget          => '/Widgets/Form/Integer',
+        WidgetArguments => {
+            Description => 'Database port',         #loc
+            Default     => 1,
+            DefaultLabel =>
+              'Leave empty to use the default value for your database',              #loc
+        },
+    },
+    DatabaseName => {
+        Widget          => '/Widgets/Form/String',
+        WidgetArguments => {
+            Description => 'Database name',                       #loc
+        },
+    },
+    DatabaseAdmin => {
+        Widget          => '/Widgets/Form/String',
+        WidgetArguments => {
+            Default => 1,
+            Hints => "Leave this alone to use the default dba username for your database type", #loc
+            Description => 'DBA username', # loc
+            DefaultLabel => '',
+        },
+    },
+    DatabaseAdminPassword => {
+        Widget          => '/Widgets/Form/String',
+        WidgetArguments => {
+            Description => 'DBA password',  #loc
+            DefaultLabel => "The DBA's database password",#loc
+            Type => 'password',
+            Hints => "You must provide the dba's password so we can create the RT database and user.",
+        },
+    },
+    DatabaseUser => {
+        Widget          => '/Widgets/Form/String',
+        WidgetArguments => {
+            Description => 'Database username for RT',                      #loc
+            Hints => 'RT will connect to the database using this user.  It will be created for you.', #loc
+        },
+    },
+    DatabasePassword => {
+        Widget          => '/Widgets/Form/String',
+        WidgetArguments => {
+            Description => 'Database password for RT',                      #loc
+            Type        => 'password',
+            Hints       => 'The password RT should use to connect to the database.',
+        },
+    },
+    DatabaseRequireSSL => {
+        Widget          => '/Widgets/Form/Boolean',
+        WidgetArguments => {
+            Description => 'Use SSL?',    # loc
+        },
+    },
+    rtname => {
+        Widget          => '/Widgets/Form/String',
+        WidgetArguments => {
+            Description => 'Site name',                        #loc
+            Hints => 'RT will use this string to uniquely identify your installation and looks for it in the subject of emails to decide what ticket a message applies to.  We recommend that you set this to your internet domain. (ex: example.com)' #loc
+        },
+    },
+    MinimumPasswordLength => {
+        Widget          => '/Widgets/Form/Integer',
+        WidgetArguments => {
+            Description => 'Minimum password length',    #loc
+        },
+    },
+    Password => {
+        Widget          => '/Widgets/Form/String',
+        WidgetArguments => {
+            Description => 'Administrative password', #loc
+            Hints => 'RT will create a user called "root" and set this as their password', #loc
+            Type => 'password',
+        },
+    },
+    OwnerEmail => {
+        Widget          => '/Widgets/Form/String',
+        WidgetArguments => {
+            Description => 'RT Administrator Email',                   #loc
+            Hints => "When RT can't handle an email message, where should it be forwarded?", #loc
+        },
+    },
+    CommentAddress => {
+        Widget          => '/Widgets/Form/String',
+        WidgetArguments => {
+            Description => 'Comment address',                           #loc
+            Hints =>
+'the default addresses that will be listed in From: and Reply-To: headers of comment mail.' #loc
+        },
+    },
+    CorrespondAddress => {
+        Widget          => '/Widgets/Form/String',
+        WidgetArguments => {
+            Description => 'Correspond address',    #loc
+            Hints =>
+'the default addresses that will be listed in From: and Reply-To: headers of correspondence mail.' #loc
+        },
+    },
+    SendmailPath => {
+        Widget          => '/Widgets/Form/String',
+        WidgetArguments => {
+            Hints => 'Where to find your sendmail binary.',    #loc
+            Description => 'Path to sendmail', #loc
+        },
+    },
+    WebDomain => {
+        Widget          => '/Widgets/Form/String',
+        WidgetArguments => {
+            Description => 'Domain name',                  #loc
+            Hints => "Don't include http://, just something like 'localhost', 'rt.example.com'", #loc
+        },
+    },
+    WebPort => {
+        Widget          => '/Widgets/Form/Integer',
+        WidgetArguments => {
+            Description => 'Web port',                     #loc
+            Hints => 'which port your web server will listen to, e.g. 8080', #loc
+        },
+    },
+
+);
+
+my $HAS_DATETIME_TZ = eval { require DateTime::TimeZone };
+
+if ($HAS_DATETIME_TZ) {
+    $Meta{Timezone} = {
+        Widget          => '/Widgets/Form/Select',
+        WidgetArguments => {
+            Description => 'Timezone',                              #loc
+            Callback    => sub {
+                my $ret;
+                $ret->{Values} = ['', DateTime::TimeZone->all_names];
+
+                my $has_datetime = eval { require DateTime };
+                if ( $has_datetime ) {
+                    my $dt = DateTime->now;
+                    for my $tz ( DateTime::TimeZone->all_names ) {
+                        $dt->set_time_zone( $tz );
+                        $ret->{ValuesLabel}{$tz} =
+                            $tz . ' ' . $dt->strftime('%z');
+                    }
+                }
+                $ret->{ValuesLabel}{''} = 'System Default'; #loc
+
+                return $ret;
+            },
+        },
+    };
+}
+else {
+    $Meta{Timezone} = {
+        Widget          => '/Widgets/Form/String',
+        WidgetArguments => {
+            Description => 'Timezone',                              #loc
+        },
+    };
+}
+
+sub Meta {
+    my $class = shift;
+    my $type  = shift;
+    return $Meta{$type} if $type;
+    return \%Meta;
+}
+
+sub CurrentValue {
+    my $class = shift;
+    my $type  = shift;
+    $type = $class if !ref $class && $class && $class ne 'RT::Installer';
+
+    return undef unless $type;
+    return $RT::Installer
+      && exists $RT::Installer->{InstallConfig}{$type}
+      ? $RT::Installer->{InstallConfig}{$type}
+      : scalar RT->Config->Get($type);
+}
+
+sub CurrentValues {
+    my $class = shift;
+    my @types = @_;
+    push @types, $class if !ref $class && $class && $class ne 'RT::Installer';
+
+    return { map { $_ => CurrentValue($_) } @types };
+}
+
+sub ConfigFile {
+    require File::Spec;
+    return File::Spec->catfile( $RT::EtcPath, 'RT_SiteConfig.pm' );
+}
+
+sub SaveConfig {
+    my $class = shift;
+
+    my $file = $class->ConfigFile;
+
+    my $content;
+
+    {
+        local $/;
+        open my $fh, '<', $file or die $!;
+        $content = <$fh>;
+        $content =~ s/^\s*1;\s*$//m;
+    }
+
+    # make organization the same as rtname
+    $RT::Installer->{InstallConfig}{Organization} =
+      $RT::Installer->{InstallConfig}{rtname};
+
+    if ( open my $fh, '>', $file ) {
+        for ( keys %{ $RT::Installer->{InstallConfig} } ) {
+
+            # we don't want to store root's password in config.
+            next if $_ eq 'Password';
+
+            $RT::Installer->{InstallConfig}{$_} = ''
+              unless defined $RT::Installer->{InstallConfig}{$_};
+
+            # remove obsolete settings we'll add later
+            $content =~ s/^\s* Set \s* \( \s* \$$_ .*$//xm;
+
+            $content .= "Set( \$$_, '$RT::Installer->{InstallConfig}{$_}' );\n";
+        }
+        $content .= "1;\n";
+        print $fh $content;
+        close $fh;
+
+        return ( 1, "Successfully saved configuration to $file." );
+    }
+
+    return ( 0, "Cannot save configuration to $file: $!" );
+}
+
+=head1 NAME
+
+    RT::Installer - RT's Installer
+
+=head1 SYNOPSYS
+
+    use RT::Installer;
+    my $meta = RT::Installer->Meta;
+
+=head1 DESCRIPTION
+
+C<RT::Installer> class provides access to RT Installer Meta
+
+=cut
+
+eval "require RT::Installer_Vendor";
+if ($@ && $@ !~ qr{^Can't locate RT/Installer_Vendor.pm}) {
+    die $@;
+};
+
+eval "require RT::Installer_Local";
+if ($@ && $@ !~ qr{^Can't locate RT/Installer_Local.pm}) {
+    die $@;
+};
+
+1;
+