These forums are locked and archived, but all topics have been migrated to the new forum. You can search for this topic on the new forum: Search for [Solved] Writing a script installer for Concrete 5 (SCRIPT ALSO INSIDE FOR YOUR USE) on the new forum.
##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.
Hi Chris,
thanks for sharing this with us. Excellent script!
Concrete5 is a very solid CMS, for the record.
Joe
Hey, this looks fantastic! Any chance it would still be compatible with the newest version of virtualmin?
Either way, great job :)