[Solved] Writing a script installer for Concrete 5 (SCRIPT ALSO INSIDE FOR YOUR USE)

4 posts / 0 new
Last post
#1 Wed, 01/16/2013 - 15:21
Elsys

[Solved] Writing a script installer for Concrete 5 (SCRIPT ALSO INSIDE FOR YOUR USE)

Copy this to /usr/libexec/webmin/virtual-server/scripts/concrete.pl or /usr/share/webmin/virtual-server/scripts/concrete.pl or /etc/webmin/virtual-server/scripts/concrete.pl

Enjoy and hopefully we can see more of this sort of collaboration from others... For scripts that the Virtualmin team hasn't gotten around to putting in yet or perhaps they aren't popular enough. This one is for an open source CMS that totally rocks, its almost a website builder but it's much more at the same time.

Sun, 01/27/2013 - 22:22
Elsys

##Script:concrete.pl
##Author: Christopher Evans (Elsys)
##Organization: Network System Solutions
##City/State: Arco, ID
##cevans@nsystemsolutions.com

sub script_concrete_desc
{
return "Concrete 5 CMS";
}

sub script_concrete_longdesc
{
return "Concrete 5 is a feature rich Content management system that allows you to deploy fantastic looking websites.";
}

sub script_concrete_uses
{
return ( "php" );
}

sub script_concrete_versions
{
return ( "5.6.0.2" );
}

sub script_concrete_category
{
return "Content Management System";
}

sub script_concrete_php_vers
{
return (5);
}

sub script_concrete_php_modules
{
return ("mysql", "mbstring", "gd", "openssl", "zip");
}

sub script_concrete_depends
{
local($d, $ver) = @_;
&has_domain_databases($d, [ "mysql"]) ||
return "Concrete requires a MySql database!" if(!@dbs);
&require_mysql();
if (&mysql::get_mysql_version() < 5) {
return "Concrete requires MySql version 5 or greater!";
}
return undef;
}

sub script_concrete_dbs
{
local ($d, $ver) = @_;
return ("mysql");
}

sub script_concrete_params
{
local($d, $ver, $upgrade) = @_;
local $rv;
local $hdir = &public_html_dir($d, 1);
if($upgrade){
local($dbtype, $dbname) = split(/_/, $upgrade->{'opts'}->{'db'}, 2);
$rv .= &ui_table_row("Database for Concrete5". $dbname);
local $dir = $upgrade->{'opts'}->{'dir'};
$dir =~ s/^$d->{'home'}\///;
$rv .= &ui_table_row("Install directory", $dir);
$rv .= &ui_table_row("Site Name", $upgrade->{'opts'}->{'sitename'});
$rv .= &ui_table_row("E-Mail", $upgrade->{'opts'}->{'email'});
}
else {
#additional install paramaters
local @dbs = &domain_databases($d, [ "mysql" ]);
$rv .= &ui_table_row("Database for Concrete5",
&ui_database_select("db","undef", \@dbs, $d, "Concrete"));
$rv .= &ui_table_row("Install sub-directory under $hdir",
&ui_opt_textbox("dir", "concrete", 30, "At top level"));
$rv .= &ui_table_row("Select E-Mail Address",
&ui_opt_textbox("email", "My Other E-Mail", 30, "Virtual Hosts Email"));
}
return $rv;
}

sub script_concrete_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";
$in{'email_def'} || $in{'email'} =~ /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i ||
return "Invalid E-Mail address!";
local $email = $in{'email_def'} ? 0 : $in{'email'};
local $dir = $in{'dir_def'} ? $hdir : "$hdir/$in{'dir'}";
local ($newdb) = ($in->{'db'} =~ s/^\*//);
return { 'db' => $in->{'db'},
'newdb' => $newdb,
'multi' => $in->{'multi'},
'dir' => $dir,
'path' => $in{'dir_def'} ? "/" : "/$in{'dir'}",
'email' => $email};
}
}

sub script_concrete_check
{
local ($d, $ver, $opts, $upgrade) = @_;
$opts->{'dir'} =~ /^\// || return "Missing or invalid install directory";
$opts->{'db'} || return "Missing database";
if (-r "$opts->{'dir'}/concrete/dispatcher.php") {
return "Concrete appears to be already installed in the selected directory";
}
if($in['cpass']){
if(length($in['cpass']) < 6){
return "Concrete requires passwords to be at least six characters!";
}
}
local ($dbtype, $dbname) = split(/_/, $opts->{'db'}, 2);
local $clash = &find_database_table($dbtype, $dbname, "C5_.*");
$clash && return "Concrete appears to already be using the desired database (table $clash)";
return undef;
}

sub script_concrete_files
{
local ($d, $ver, $opts, $upgrade) = @_;
local @files = ( { 'name' => "source",
'file' => "concrete5.6.0.2.zip",
'url' => "http://www.concrete5.org/download_file/-/view/44326/8497/",
'nocache' => 1 } );
return @files;
}

sub script_concrete_commands
{
return ("unzip");
}

sub script_concrete_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 $email = $opts->{'email'};
if($opts->{'email'} == 0){
$email = $d->{'emailto'};
}
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 $dbphptype = $dbtype eq "mysql" ? &mysql_pass($d) : &postgres_pass($d, 1);
local $dbhost = &get_database_host($dbtype);
local $dberr = &check_script_db_connection($dbtype, $dbname, $dbuser, $dbpass);
return(0, "Database connection failed : $dberr") if ($dberr);
# Create target dir
if (!-d $opts->{'dir'}) {
$out = &run_as_domain_user($d, "mkdir -p ".quotemeta($opts->{'dir'}));
-d $opts->{'dir'} ||
return (0, "Failed to create directory : $out.");
}
# Extract tar file to temp dir
local $temp = &transname();
mkdir($temp, 0755);
chown($d->{'uid'}, $d->{'gid'}, $temp);
$out = &run_as_domain_user($d, "cd ".quotemeta($temp).
" && unzip $files->{'source'}");
local $verdir = "concrete5.6.0.2";
-r "$temp/$verdir/concrete/dispatcher.php" ||
return (0, "Failed to extract source : $out.");

# Move html dir to target
$out = &run_as_domain_user($d, "cp -rp ".quotemeta($temp)."/$verdir/* ".
quotemeta($opts->{'dir'}));
local $testpath = "$opts->{'dir'}/concrete/dispatcher.php";
-r $testpath || return (0, "Failed to copy source : $out.");
#Invoke concrete installer!
local $ipage = $opts->{'path'}."/index.php";
local ($ierror);
local $iout = $opts->{'path'}."/install.tmp";
local @params = (
[ "SITE", "www.".$d->{'dom'} ],
[ "uEmail", $email ],
[ "uPassword", $dompass ],
[ "uPasswordConfirm", $dompass ],
[ "locale", "" ],
[ "DB_SERVER", $dbhost ],
[ "DB_USERNAME", $dbuser ],
[ "DB_PASSWORD", $dbpass ],
[ "DB_DATABASE", $dbname ],
[ "SAMPLE_CONTENT", "standard"],
);
$ipage = $opts->{'path'}."/index.php/install/-/configure/";
local $params = join("&", map { $_->[0]."=".&urlize($_->[1]) } @params);
&http_post("www.$d->{'dom'}", $d->{'web_port'}, $ipage, $params, $iout, \$ierror);
if($ierror) {
return(0, "Concrete 5 post-install configuration failed, if running php under cgi mode cgi.fixpathinfo must be enabled : $ierror");
}
print "Post data accepted final processing commencing!";
$out = &run_as_domain_user($d, "rm -f ".quotemeta($opts->{'dir'}."/install.tmp"));
# Return a URL for the user
local $url = &script_path_url($d, $opts);
local $rp = $opts->{'dir'};
$rp =~ s/^$d->{'home'}\///;
return (1, "Concrete 5 installation complete. It can be accessed at $url.", "Under $rp", $url, "admin", $dompass);
}

sub script_concrete_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);

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

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

sub script_concrete_site
{
return "http://www.concrete5.org/";
}

sub script_concrete_gpl
{
return 1;
}

1;

Modified needed to fix email regex forgot a $ on line 94 and added additional description to error message for those running php via cgi. That being this script requires cgi.pathinfo=1 otherwise it won't execute it's a requirement of the underlying concrete installer.

Thu, 01/17/2013 - 08:46
BossHog

Hi Chris,
thanks for sharing this with us. Excellent script!
Concrete5 is a very solid CMS, for the record.
Joe

Wed, 02/10/2016 - 08:44
kk21

Hey, this looks fantastic! Any chance it would still be compatible with the newest version of virtualmin?

Either way, great job :)

Topic locked