
# script_horde_desc()
sub script_horde_desc
{
return "Horde";
}

sub script_horde_uses
{
return ( "php" );
}

sub script_horde_longdesc
{
return "Horde is a framework for PHP applications. It is typically used in conjunction with other scripts such as IMP (for webmail) and Kronolith (for calendars)";
}

# script_horde_versions()
sub script_horde_versions
{
return ( "3.3.13" );
}

sub script_horde_category
{
return "Horde";
}

sub script_horde_php_vers
{
return ( 5 );
}

sub script_horde_pear_modules
{
return ("Log", "Mail-1.1.14", "Mail_Mime", "DB");
}

sub script_horde_php_modules
{
local ($d, $ver, $phpver, $opts) = @_;
return ("imap", $phpver >= 5 ? "dom" : "domxml", "mysql");
}

sub script_horde_dbs
{
return ("mysql", "postgres");
}

# script_horde_params(&domain, version, &upgrade-info)
# Returns HTML for table rows for options for installing PHP-NUKE
sub script_horde_params
{
local ($d, $ver, $upgrade) = @_;
local $rv;
local $hdir = &public_html_dir($d, 1);
if ($upgrade) {
	# Options are fixed when upgrading
	local ($dbtype, $dbname) = split(/_/, $upgrade->{'opts'}->{'db'}, 2);
	$rv .= &ui_table_row("Database for Horde", $dbname);
	local $dir = $upgrade->{'opts'}->{'dir'};
	$dir =~ s/^$d->{'home'}\///;
	$rv .= &ui_table_row("Install directory", $dir);
	}
else {
	# Show editable install options
	local @dbs = &domain_databases($d, [ "mysql", "postgres" ]);
	$rv .= &ui_table_row("Database for Horde",
		     &ui_database_select("db", undef, \@dbs, $d, "horde"));
	$rv .= &ui_table_row("Install sub-directory under <tt>$hdir</tt>",
			     &ui_opt_textbox("dir", &substitute_scriptname_template("horde", $d), 30, "At top level"));
	}
return $rv;
}

# script_horde_parse(&domain, version, &in, &upgrade-info)
# Returns either a hash ref of parsed options, or an error string
sub script_horde_parse
{
local ($d, $ver, $in, $upgrade) = @_;
if ($upgrade) {
	# Options are always the same
	return $upgrade->{'opts'};
	}
else {
	local $hdir = &public_html_dir($d, 0);
	$in{'dir_def'} || $in{'dir'} =~ /\S/ && $in{'dir'} !~ /\.\./ ||
		return "Missing or invalid installation directory";
	local $dir = $in{'dir_def'} ? $hdir : "$hdir/$in{'dir'}";
	local ($newdb) = ($in->{'db'} =~ s/^\*//);
	return { 'db' => $in->{'db'},
		 'newdb' => $newdb,
		 'dir' => $dir,
		 'path' => $in{'dir_def'} ? "/" : "/$in{'dir'}", };
	}
}

# script_horde_check(&domain, version, &opts, &upgrade-info)
# Returns an error message if a required option is missing or invalid
sub script_horde_check
{
local ($d, $ver, $opts, $upgrade) = @_;
$opts->{'dir'} =~ /^\// || return "Missing or invalid install directory";
$opts->{'db'} || return "Missing database";
if (-r "$opts->{'dir'}/index.php") {
	return "Horde appears to be already installed in the selected directory";
	}
local ($dbtype, $dbname) = split(/_/, $opts->{'db'}, 2);
local $clash = &find_database_table($dbtype, $dbname, "horde_users");
$clash && return "Horde appears to be already using the selected database (table $clash)";
return undef;
}

# script_horde_files(&domain, version, &opts, &upgrade-info)
# Returns a list of files needed by Horde, each of which is a hash ref
# containing a name, filename and URL
sub script_horde_files
{
local ($d, $ver, $opts, $upgrade) = @_;
local @files = ( { 'name' => "source",
	   'file' => "horde-$ver.tar.gz",
	   'nocheck' => 1,
	   'url' => "ftp://ftp.horde.org/pub/horde/horde-$ver.tar.gz" } );
return @files;
}

sub script_horde_commands
{
return ("tar", "gunzip");
}

# script_horde_install(&domain, version, &opts, &files, &upgrade-info)
# Actually installs Horde, and returns either 1 and an informational
# message, or 0 and an error
sub script_horde_install
{
local ($d, $version, $opts, $files, $upgrade, $domuser, $dompass) = @_;
local ($out, $ex);
if ($opts->{'newdb'} && !$upgrade) {
        local $err = &create_script_database($d, $opts->{'db'});
        return (0, "Database creation failed : $err") if ($err);
        }
local ($dbtype, $dbname) = split(/_/, $opts->{'db'}, 2);
local $dbuser = $dbtype eq "mysql" ? &mysql_user($d) : &postgres_user($d);
local $dbpass = $dbtype eq "mysql" ? &mysql_pass($d) : &postgres_pass($d, 1);
local $dbhost = &get_database_host($dbtype, $d);
local $dbphptype = $dbtype eq "mysql" ? "mysql" : "psql";
local $dberr = &check_script_db_connection($dbtype, $dbname, $dbuser, $dbpass);
return (0, "Database connection failed : $dberr") if ($dberr);

# Extract tar file to temp dir and copy to target
local $temp = &transname();
local $err = &extract_script_archive($files->{'source'}, $temp, $d,
                                     $opts->{'dir'}, "horde-$ver");
$err && return (0, "Failed to extract source : $err");

# Copy the config files
local $cdir = "$opts->{'dir'}/config";
opendir(DIR, $cdir);
foreach my $f (readdir(DIR)) {
	if ($f =~ /^(.*)\.dist$/ && !-r "$cdir/$1") {
		&run_as_domain_user($d, "cp ".quotemeta("$cdir/$f")." ".
					      quotemeta("$cdir/$1"));
		&make_file_php_writable($d, "$cdir/$1");
		}
	}
closedir(DIR);
&make_file_php_writable($d, $cdir);

if (!$upgrade) {
	# Add SQL config settings
	local $lref = &read_file_lines_as_domain_user($d, "$cdir/conf.php");
	push(@$lref, "\$conf['sql']['hostspec'] = '$dbhost';");
	push(@$lref, "\$conf['sql']['username'] = '$dbuser';");
	push(@$lref, "\$conf['sql']['password'] = '".
		     &php_quotemeta($dbpass, 1)."';");
	push(@$lref, "\$conf['sql']['protocol'] = 'unix';");
	push(@$lref, "\$conf['sql']['database'] = '$dbname';");
	push(@$lref, "\$conf['sql']['phptype'] = '$dbphptype';");
	push(@$lref, "\$conf['sql']['charset'] = 'iso-8859-1';");

	&open_socket("localhost", 143, IMAP, \$error);
	close(IMAP);
	if (!$error) {
		# Use IMAP auth
		push(@$lref, "\$conf['auth']['driver'] = 'imap';");
		push(@$lref, "\$conf['auth']['params']['hostspec'] = 'localhost';");
		push(@$lref, "\$conf['auth']['params']['port'] = 143;");
		push(@$lref, "\$conf['auth']['params']['protocol'] = 'imap/notls';");
		push(@$lref, "\$conf['auth']['params']['imapconfig'] = 'separate';");
		}
	elsif ($config{'ftp'}) {
		# Use FTP auth
		push(@$lref, "\$conf['auth']['driver'] = 'ftp';");
		push(@$lref, "\$conf['auth']['params']['hostspec'] = 'localhost';");
		push(@$lref, "\$conf['auth']['params']['port'] = 21;");
		}
	push(@$lref, "\$conf['auth']['admins'] = array('Administrator', '$domuser');");

	# Use SQL for prefs
	push(@$lref, "\$conf['prefs']['params']['driverconfig'] = 'horde';");
	push(@$lref, "\$conf['prefs']['params']['charset'] = 'iso-8859-1';");
	push(@$lref, "\$conf['prefs']['driver'] = 'sql';");
	push(@$lref, "\$conf['datatree']['params']['driverconfig'] = 'horde';");
	push(@$lref, "\$conf['datatree']['params']['charset'] = 'iso-8859-1';");
	push(@$lref, "\$conf['datatree']['driver'] = 'sql';");
	push(@$lref, "\$conf['cache']['driver'] = 'file';");

	# Basic mailer params
	push(@$lref, "\$conf['mailer']['params']['auth'] = '0';");
	push(@$lref, "\$conf['mailer']['type'] = 'smtp';");

	# Basic logging settings
	local $logfile = "$d->{'home'}/logs/horde.log";
	&open_tempfile_as_domain_user($d, LOG, ">>$logfile", 0, 1);
	&close_tempfile_as_domain_user($d, LOG);
	&set_permissions_as_domain_user($d, 0777, $logfile);
	push(@$lref, "\$conf['log']['priority'] = PEAR_LOG_NOTICE;");
	push(@$lref, "\$conf['log']['ident'] = 'HORDE';");
	push(@$lref, "\$conf['log']['params'] = array();");
	push(@$lref, "\$conf['log']['name'] = '$logfile';");
	push(@$lref, "\$conf['log']['params']['append'] = true;");
	push(@$lref, "\$conf['log']['type'] = 'file';");
	push(@$lref, "\$conf['log']['enabled'] = true;");

	# Cookie path
	push(@$lref, "\$conf['cookie']['path'] = '$opts->{'path'}';");

	&flush_file_lines_as_domain_user($d, "$cdir/conf.php");
	}

# Create the database tables
if (!$upgrade) {
	if ($dbtype eq "mysql") {
		# Only run the create table SQL commands, in our database
		&require_mysql();
		local $sqlfile = "$opts->{'dir'}/scripts/sql/create.mysql.sql";
		local $temp = &tempname("create.mysql.sql");
		&open_readfile_as_domain_user($d, IN, $sqlfile);
		&open_tempfile(OUT, ">$temp");
		while(<IN>) {
			if (/^create\s+table/i) {
				print OUT $_;
				while(<IN>) {
					print OUT $_;
					last if (/^\);/ ||
						 /^\)\s+ENGINE\s*=\s*\S+;/i);
					}
				}
			elsif (/^create\s+index/i) {
				print OUT $_;
				}
			}
		&close_readfile_as_domain_user($d, IN);
		&close_tempfile(OUT);
		($ex, $out) = &mysql::execute_sql_file($dbname, $temp, $dbuser, $dbpass);
		$ex && return (-1, "Failed to run database setup script : <tt>$out</tt>.");
		unlink($temp);
		}
	elsif ($dbtype eq "postgres") {
		# Nothing needed in this case .. I guess Horde creates the
		# tables automatically?
		}
	}

# Add the lib dir to the PHP path
my $phpmode = &get_domain_php_mode($d);
if ($phpmode ne "mod_php") {
	my ($ini) = grep { $_->[0] == $opts->{'phpver'} }
			 &list_domain_php_inis($d);
	local $cmd = &get_php_cli_command($opts->{'phpver'});
	if ($ini && $cmd) {
		my $ipath = &backquote_command(
			"$cmd -B 'echo ini_get(\"include_path\");' </dev/null");
		if ($ipath && !$?) {
			&foreign_require("phpini", "phpini-lib.pl");
			local $pconf = &phpini::get_config($ini->[1]);
			&phpini::save_directive($pconf, "include_path",
						"$ipath:$opts->{'dir'}/lib");
			&flush_file_lines($ini->[1]);
			&register_post_action(\&restart_apache);
			}
		}
	}

# Return a URL for the user
local $url = &script_path_url($d, $opts);
local $rp = $opts->{'dir'};
$rp =~ s/^$d->{'home'}\///;
return (1, "Horde installation complete. It can be accessed at <a target=_blank href='$url'>$url</a>. You will need to go to the Setup page under the Administration section to perform further configuration.", "Under $rp using $dbphptype database $dbname", $url, $domuser);
}

# script_horde_uninstall(&domain, version, &opts)
# Un-installs a Horde installation, by deleting the directory and database.
# Returns 1 on success and a message, or 0 on failure and an error
sub script_horde_uninstall
{
local ($d, $version, $opts) = @_;

# Check for other horde-dependent scripts
local @scripts = &list_domain_scripts($d);
local ($dep) = grep { $_->{'opts'}->{'horde'} } @scripts;
if ($dep) {
	return (0, "The script $dep->{'name'} which depends on Horde ".
		   "is still installed");
	}

# Remove horde tables from the database
&cleanup_script_database($d, $opts->{'db'}, "horde_");

# Remove the contents of the target directory
local $derr = &delete_script_install_directory($d, $opts);
return (0, $derr) if ($derr);

# Take out the DB
if ($opts->{'newdb'}) {
        &delete_script_database($d, $opts->{'db'});
        }

return (1, "Horde directory and tables deleted.");
}

# script_horde_latest()
# Returns a URL and regular expression or callback func to get the version
sub script_horde_latest
{
return ( "http://ftp.horde.org/pub/horde/",
	 "horde-([0-9\\.]+)\\.tar\\.gz" );
}

sub script_horde_site
{
return 'http://www.horde.org/';
}

sub script_horde_passmode
{
return 3;
}

sub script_horde_disabled
{
return 2;
}

1;

