
# script_zenphoto_desc()
sub script_zenphoto_desc
{
return "Zenphoto";
}

sub script_zenphoto_uses
{
return ( "php" );
}

sub script_zenphoto_longdesc
{
return "Zenphoto is a standalone CMS for multimedia focused websites";
}

# script_zenphoto_versions()
sub script_zenphoto_versions
{
return ( "1.6" );
}

sub script_zenphoto_category
{
return ("Photos", "CMS");
}

sub script_zenphoto_php_vers
{
return ( 5 );
}

sub script_zenphoto_php_vars
{
return ( 
     [ 'memory_limit', '128M', '+' ],
     [ 'post_max_size', '1G', '+' ],
     [ 'upload_max_filesize', '1G', '+' ],
	 [ 'file_uploads', 'On' ] );
}

sub script_zenphoto_php_modules
{
return ("gd", "mysql", "tidy", "zip");
}

sub script_zenphoto_dbs
{
return ("mysql");
}

# script_zenphoto_params(&domain, version, &upgrade-info)
# Returns HTML for table rows for options for installing Wordpress
sub script_zenphoto_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 Zenphoto tables", $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" ]);
	$rv .= &ui_table_row("Database for Zenphoto tables",
		     &ui_database_select("db", undef, \@dbs, $d, "zenphoto"));
	$rv .= &ui_table_row("Install sub-directory under <tt>$hdir</tt>",
			     &ui_opt_textbox("dir", &substitute_scriptname_template("zenphoto", $d), 30, "At top level"));
	}
return $rv;
}

# script_zenphoto_parse(&domain, version, &in, &upgrade-info)
# Returns either a hash ref of parsed options, or an error string
sub script_zenphoto_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_zenphoto_check(&domain, version, &opts, &upgrade-info)
# Returns an error message if a required option is missing or invalid
sub script_zenphoto_check
{
local ($d, $ver, $opts, $upgrade) = @_;
$opts->{'dir'} =~ /^\// || return "Missing or invalid install directory";
$opts->{'db'} || return "Missing database";
if (-r "$opts->{'dir'}/zen/zp-config.php" ||
    -r "$opts->{'dir'}/zp-core/zp-config.php") {
	return "Zenphoto appears to be already installed in the selected directory";
	}
local ($dbtype, $dbname) = split(/_/, $opts->{'db'}, 2);
local $clash = &find_database_table($dbtype, $dbname, "zenphoto_.*");
$clash && return "Zenphoto appears to be already using the selected database (table $clash)";
return undef;
}

# script_zenphoto_files(&domain, version, &opts, &upgrade-info)
# Returns a list of files needed by Wordpress, each of which is a hash ref
# containing a name, filename and URL
sub script_zenphoto_files
{
local ($d, $ver, $opts, $upgrade) = @_;
local @files = ( { 'name' => "source",
	'file' => "zenphoto-$ver.zip",
	'method' => 'GET',
	'url' => "https://github.com/zenphoto/zenphoto/archive/v${ver}.zip" } );
return @files;
}

sub script_zenphoto_commands
{
return ("unzip");
}

# script_zenphoto_install(&domain, version, &opts, &files, &upgrade-info)
# Actually installs Zenphoto, and returns either 1 and an informational
# message, or 0 and an error
sub script_zenphoto_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 = &mysql_user($d);
local $dbpass = &mysql_pass($d);
local $dbhost = &get_database_host("mysql", $d);
local $dberr = &check_script_db_connection($dbtype, $dbname, $dbuser, $dbpass);
return (0, "Database connection failed : $dberr") if ($dberr);

# Preserve old albums dir if upgrading
local $adir = "$opts->{'dir'}/albums";
if ($upgrade && -d $adir) {
	&rename_as_domain_user($d, $adir, $adir.".orig");
	}

# Extract tar file to temp dir and copy to target
local $temp = &transname();
local $err = &extract_script_archive($files->{'source'}, $temp, $d,
                                     $opts->{'dir'}, "zenphoto*");
$err && return (0, "Failed to extract source : $err");
local $cfile = "$opts->{'dir'}/zp-data/zenphoto.cfg.php";
local $cfileold = "$opts->{'dir'}/zen/zp-config.php";
if (!-r $cfileold) {
	$cfileold = "$opts->{'dir'}/zp-core/zp-config.php";
	}
if (!-r $cfileold) {
	$cfileold = "$opts->{'dir'}/zp-core/zenphoto.cfg";
	}
if (!-r $cfileold) {
	$cfileold = "$opts->{'dir'}/zp-data/zenphoto.cfg";
	}

# Create a test file needed for charset detection
&open_tempfile(CHARSET, ">$opts->{'dir'}/zp-data/charset_t".chr(232)."st");
&close_tempfile(CHARSET);

# Create an empty writable .htaccess file, if missing
local $htaccess = "$opts->{'dir'}/.htaccess";
if (-e $htaccess) {
	&open_tempfile_as_domain_user($d, HT, ">$htaccess");
	&close_tempfile_as_domain_user($d, HT);
	&make_file_php_writable($d, $htaccess);
	}

local $cfilesrc = "$opts->{'dir'}/zp-core/zenphoto_cfg.txt";
if (-r $cfilesrc && !-r $cfile && !-r $cfileold) {
	# Copy in template config file
	&make_dir_as_domain_user($d, "$opts->{'dir'}/zp-data");
	&run_as_domain_user($d, "cp ".quotemeta($cfilesrc)." ".
				      quotemeta($cfile));
	}

if (!-r $cfile && $upgrade && -r $cfileold) {
	# Config file has moved in new version
	&run_as_domain_user($d, "cp ".quotemeta($cfileold)." ".
				      quotemeta($cfile));
	}
elsif (!$upgrade) {
	local $lref = &read_file_lines_as_domain_user($d, $cfile);
	local $l;
	foreach $l (@$lref) {
		if ($l =~ /^\$conf\['mysql_user'\]\s*=/) {
			$l = "\$conf['mysql_user'] = \"$dbuser\";";
			}
		if ($l =~ /^\$conf\['mysql_pass'\]\s*=/) {
			$l = "\$conf['mysql_pass'] = \"".
			     &php_quotemeta($dbpass)."\";";
			}
		if ($l =~ /^\$conf\['mysql_host'\]\s*=/) {
			$l = "\$conf['mysql_host'] = \"$dbhost\";";
			}
		if ($l =~ /^\$conf\['mysql_database'\]\s*=/) {
			$l = "\$conf['mysql_database'] = \"$dbname\";";
			}
		if ($l =~ /^\$conf\['mysql_prefix'\]\s*=/) {
			$l = "\$conf['mysql_prefix'] = \"zenphoto_\";";
			}
		if ($l =~ /^\$conf\['mod_rewrite'\]\s*=/) {
			$l = "\$conf['mod_rewrite'] = false;";
			}
		if ($l =~ /^\$conf\['adminuser'\]\s*=/) {
			$l = "\$conf['adminuser'] = \"$domuser\";";
			}
		if ($l =~ /^\$conf\['adminpass'\]\s*=/) {
			$l = "\$conf['adminpass'] = \"$dompass\";";
			}
		if ($l =~ /^\$conf\['admin_email'\]\s*=/) {
			$l = "\$conf['admin_email'] = \"$d->{'emailto_addr'}\";";
			}
		if ($l =~ /define\('WEBPATH'/) {
			$l = "define('WEBPATH', '$opts->{'path'}');";
			}
		if ($l =~ /define\('SERVERPATH'/) {
			$l = "define('SERVERPATH', '$opts->{'dir'}');";
			}
		}
	&flush_file_lines_as_domain_user($d, $cfile);
	}

# Make the albums and cache directories writable
if ($upgrade) {
	# Put back albums dir
	&unlink_file_as_domain_user($d, $adir);
	&rename_as_domain_user($d, $adir.".orig", $adir);
	}
else {
	&make_dir_as_domain_user($d, $adir, 0777);
	&make_file_php_writable($d, $adir, 1);
	}
local $cdir = "$opts->{'dir'}/cache";
&make_dir_as_domain_user($d, $cdir, 0777);
&make_file_php_writable($d, $cdir, 1);

# Create DB tables
local $dbpage = "$opts->{'path'}/zp-core/setup/index.php?checked&create=zenphoto_options,zenphoto_albums,zenphoto_images,zenphoto_comments,zenphoto_administrators,zenphoto_admin_to_object,zenphoto_tags,zenphoto_obj_to_tag,zenphoto_captcha,zenphoto_pages,zenphoto_news2cat,zenphoto_news_categories,zenphoto_news,zenphoto_menu,zenphoto_plugin_storage,zenphoto_search_cache";
local ($out, $error);
&get_http_connection($d, $dbpage, \$out, \$error, undef, 0, undef, undef, 600);
#if ($error || $out !~ /Done\s+with\s+table\s+(create|update)/i) {
#	return (-1, "ZenPhoto table creation failed : ".($error || $out));
#	}

if (!$upgrade) {
	# Request the initial admin page
	$out = $error = undef;
	&get_http_connection($d, "$opts->{'path'}/zp-core/admin.php",
			     \$out, \$error);
	if ($error) {
		return (-1, "Failed to get initial page : $error");
		}
	elsif ($out !~ /XSRFToken=([^ \&"]+)/) {
		return (-1, "Could not find XSRF token in initial page");
		}
	local $token = $1;

	# Accept licence
	$out = $error = undef;
	&get_http_connection($d, "$opts->{'path'}/zp-core/license.php?licenseAccept&XSRFToken=$token", \$out, \$error);

	# Request the xsrf token
	$out = $error = undef;
	&get_http_connection($d, "$opts->{'path'}/zp-core/admin-users.php",
			     \$out, \$error, \&zenphoto_cookie_callback);
	if ($error) {
		return (-1, "Failed to get XSRF token : $error");
		}
	elsif ($out !~ /id="XSRFToken"\s+value="([^"]+)"/) {
		return (-1, "Could not find XSRF token in page");
		}
	elsif (!$zenphoto_session_cookie) {
		return (-1, "No session cookie found");
		}
	local $token = $1;

	# Create admin account
	local @params = (
		[ "XSRFToken", $token ],
		[ "saveadminoptions", "yes" ],
		[ "subpage", "-1" ],
		[ "alter_enabled", "1" ],
		[ "showgroup", "" ],
		[ "show-", 1 ],
		[ "0-newuser", 1 ],
		[ "dummy", "" ],
		[ "adminuser0", $domuser ],
		[ "0-confirmed", 1 ],
		[ "passrequired0", 1 ],
		[ "pass0", $dompass ],
		[ "disclose_password0", 1 ],
		[ "pass_r0", $dompass ],
		[ "0-challengephrase", $domuser ],
		[ "0-challengeresponse", $dompass ],
		[ "0-admin_name", $d->{'owner'} ],
		[ "0-admin_email", $d->{'emailto_addr'} ],
		[ "0-admin_language", "en_US" ],
		[ "0-VIEW_FULLIMAGE_RIGHTS", 64 ],
		[ "0-VIEW_ALBUMS_RIGHTS", 512 ],
		[ "0-UPLOAD_RIGHTS", 8192 ],
		[ "0-MANAGE_ALL_ALBUM_RIGHTS", 8388608 ],
		[ "0-VIEW_GALLERY_RIGHTS", 16 ],
		[ "0-VIEW_SEARCH_RIGHTS", 32 ],
		[ "0-POST_COMMENT_RIGHTS", 2048 ],
		[ "0-COMMENT_RIGHTS", 4096 ],
		[ "0-FILES_RIGHTS", 131072 ],
		[ "0-THEMES_RIGHTS", 67108864 ],
		[ "0-TAGS_RIGHTS", 268435456 ],
		[ "0-OVERVIEW_RIGHTS", 4 ],
		[ "0-OPTIONS_RIGHTS", 536870912 ],
		[ "0-ADMIN_RIGHTS", 1073741824 ],
		[ "0-ALL_NEWS_RIGHTS", 128 ],
		[ "0-MANAGE_ALL_NEWS_RIGHTS", 2097152 ],
		[ "0-ALL_PAGES_RIGHTS", 256 ],
		[ "0-MANAGE_ALL_PAGES_RIGHTS", 4194304 ],
		[ "totaladmins", 1 ],
		[ "checkForPostTruncation", 1 ],
		[ "Apply", "Apply" ],
		);
	local $params = join("&", map { $_->[0]."=".&urlize($_->[1]) } @params);
	local $ipage = $opts->{'path'}.
		       "/zp-core/admin-users.php?action=saveoptions";

	# Make an HTTP post to the installer page
	$out = $error = undef;
	&post_http_connection($d, $ipage, $params, \$out, \$error,
		      { 'Cookie' => 'PHPSESSID='.$zenphoto_session_cookie });
	if ($error =~ /error=([^\&]+)/) {
		return (-1, "ZenPhoto account creation failed : ".
			    &un_urlize("$1"));
		}
	elsif ($error && $error !~ /Location/) {
		return (-1, "ZenPhoto account creation failed : $error");
		}

	# Delete setup file
	&unlink_file_as_domain_user($d, "$opts->{'dir'}/zp-core/setup.php");
	}

# Return a URL for the user
local $url = &script_path_url($d, $opts);
local $rp = $opts->{'dir'};
$rp =~ s/^$d->{'home'}\///;
local $adminurl = $url."zp-core/admin.php";
return (1, "Zenphoto installation complete. It can be managed at <a target=_blank href='$adminurl'>$adminurl</a> .", "Under $rp using $dbphptype database $dbname", $url, $domuser, $dompass);
}

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

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

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

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

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

# script_zenphoto_latest(version)
# Returns a URL and regular expression or callback func to get the version
sub script_zenphoto_latest
{
local ($ver) = @_;
return ( "http://www.zenphoto.org/",
	 "archive/v([0-9\\.RC_b]+).zip" );
}

sub script_zenphoto_site
{
return 'http://www.zenphoto.org/';
}

sub script_zenphoto_passmode
{

# Minimum 8 chars of alphanumeric string (unicode)
return (1, 8, '^(?=.*[\p{L}])(?=.*\d)[\p{L}\d]{8,}$');
}

sub zenphoto_cookie_callback
{
if ($WebminCore::header{'set-cookie'} =~ /PHPSESSID=([^ ;]+)/) {
	$zenphoto_session_cookie = $1;
	}
}

1;

