Friday, January 9, 2009

Joomla replication script

back to 2006/2007, 
again, my colleage handle this 1 project that require him to do more than 100 site using joomla.
our server spec:
OS : windows
Web Server : Sambar Server 7.0
Perl : 5.6
so i come out with this script.
#!/usr/bin/perl
$| = 1;
########################################
##use at ur own risk
##www.mbek.net, hairulmoktar.blogspot.com
########################################
use CGI::Carp qw(fatalsToBrowser set_message);
BEGIN {sub handle_errors { my $msg = shift;
print qq|<html><head><title>Server Error</title></head></html><body bgcolor=#ffffff leftmargin=8 topmargin=8 marginwidth=8 marginheight=8><font face=verdana color=#336699>
<h1><font color=red>Opss!! Server Error!</font></h1><div style="border: 1px solid #666666;background-color: #ffff00;padding: 10px;">$msg<p>Please inform <A HREF=mailto:my\@email.com>mbek</A> (my\@email.com)detail about about this error.</div></body></html>
<!--powered by [email protected]_kambing-->
\n|;exit;}
set_message(\&handle_errors);}
########################################
use CGI;
use File::Copy;
use DBI;
my $req = new CGI;
$vhostsloc = "/path/to/sambar70/config/vhosts.ini";
$rootdir = "/path/to/mainfolder";
$rooturl = "http://$ENV{HTTP_HOST}";
$adminemail = "admin\@somehost.com";
$db_user = "mysqlusername";
$db_password = "mysqlpassword";
$dsn = "DBI:mysql:database=joomla;host=localhost;port=3306";
print "Content-type : text/html\n\n";
print qq~
<html>
<style>
body,td,p,th,input,select{
font-family: verdana;
font-size: 10px;
}
</style>
<body>~;
if($req->param('do') eq 'docopy'){
&docopy();
}elsif($req->param('do') eq 'joomla'){
&joomla();
}elsif($req->param('do') eq 'dump'){
&dumps();
}else{
&main();
}
print qq~
</body>
</html>~;
sub main{
my %VHOSTSEXIST;
open(VHOSTS,"$vhostsloc");
my @vhostslines = <VHOSTS>;
close VHOSTS;
#print "<ol>";
foreach(@vhostslines){
$_ =~ s/[\n\r]//g;
if($_ =~ /^\[(.*?)\]/ && $_ !~ /^\[\*/){
my $hosts = $1;
if($hosts =~ /my1stopweb.com/i){
# print "<li>$hosts";
# print " : <font color=\"#ff0000\">more than 1</font>" if $VHOSTSEXIST{$hosts};
$VHOSTSEXIST{$hosts} = "$hosts";
}
}
}
#print "</ol>";
my $listofdatabases = '';
$dbh = DBI->connect($dsn,$db_user,$db_password) or die $!;
my $sth = $dbh->prepare("show databases");
$sth->execute() or die qq|Database Error:  $DBI::errstr $query|;
while (my @dbrows =  $sth->fetchrow_array ){
push @databases,"$dbrows[0]";
$listofdatabases .= qq~<option value="$dbrows[0]">$dbrows[0]</option>~ if $dbrows[0] =~ /^joomla_/i;
}
$sth->finish;
$dbh->disconnect;
my $select_sources = '';
opendir SUBDIR, "$rootdir" or die "$rootdir doesnt exist";
my @sourceslist = grep !/^\.\.?$/, readdir SUBDIR;
foreach (@sourceslist){
if(-d "$rootdir/$_"){
$select_sources .= qq~<option value="$_">$_</option>~;
if($_ !~ /old/i && $_ !~ /joomla/i){
$listeddir .= qq~<li>$_~;
$listeddir_subdomain .= qq~<li><a href="http://$_\.my1stopweb.com" target="_blank">http://$_\.my1stopweb.com</a>~;
$listeddir_email .= qq~<li>$_\@my1stopweb.com ~;
$listeddir_subdomain_vhost .= qq~[$_.my1stopweb.com]
Automatic Log mailto = 
CGI Directory = /cgi-bin/
CGI Run As = 
Default Page = index.php index.htm index.html index.stm index.asp index.pl index.cgi
Documents Directory = f:/site/my1stopweb/$_/
Log File = vhost-$_.my1stopweb.com.log
Messages Directory = messages
Tmp Directory = tmp
WEB-INF Directory = 
WinCGI Directory = /cgi-win/
~ if !$VHOSTSEXIST{$_.".my1stopweb.com"};
}
}
}
closedir SUBDIR;
print qq~
<form>
<table>
<tr>
<td>
<li>source : <select name="sources">$select_sources</select>
<li>destination : <input type="text" name="destination" value="" onkeyup="this.form.mosConfig_db.value='joomla_' + this.value;">
<li><input type="checkbox" name="replacefolder" value="1"> continue if <b>Folder</b> Exist ??
<ul>
<li><input type="checkbox" name="replacefile" value="1"> Replace <b>Existing</b> files ?? (only valid if <i>Replace <b>Folder</b> Exist</i> checked)
</ul>
</td>
</tr><tr>
<td>
** <b>optional</b>
<table border=1>
<tr>
<td><input type="checkbox" name="doconfig" value="1"></td>
<td><b>Joomla General Configuration</b></td>
</tr>
<tr>
<td> </td>
<td>
<li>Joomla Name : <input type="text" name="mosConfig_sitename" value="New Website | SMEXchange" size="50">
<li>Installation Folder : <input type="text" name="installfolder" value="installation">
<p>
<li>DB Server : <input type="text" name="mosConfig_host" value="localhost">
<li>username : <input type="text" name="mosConfig_user" value="my1stopweb">
<li>pasword : <input type="text" name="mosConfig_password" value="">
<li>Database : <input type="text" name="mosConfig_db" value="joomla_">
</td>
</tr>
<tr>
<td> </td>
<td>
<table border=0>
<tr>
<td><input type="radio" name="dbused" value="joomla" checked></td>
<td>Joomla</td>
</tr>
<tr>
<td><input type="radio" name="dbused" value="copy"></td>
<td>Copy Existing Databse</td>
</tr>
<tr>
<td> </td>
<td><select name="copyfromdb">$listofdatabases</select></td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr><tr>
<td >
<input type="checkbox" name="showprogress" value=""> Show Progress (<i>leave uncheck for faster loading...</i>)
</td>
</tr><tr>
<td >
<input type="submit" value="Copy Directory >>">
<input type="hidden" name="do" value="docopy">
</td>
</tr>
</table>
<p>
<table>
<tr>
<td>dir</td>
<td>subdomain</td>
<td>email</td>
</tr><tr>
<td>$listeddir</td>
<td>$listeddir_subdomain</td>
<td>$listeddir_email</td>
</tr><tr>
<td colspan=3><textarea rows=10 cols=100>$listeddir_subdomain_vhost</textarea></td>
</tr>
</table>
</form>
~;
exit;
}
sub docopy{
my $sourcefolder = $req->param('sources');
my $destinationfolder = $req->param('destination');
my $replacefolder = $req->param('replacefolder');
my $replacefile = $req->param('replacefile');
my $showprogress = $req->param('showprogress');
my $doconfig = $req->param('doconfig');
my $mosConfig_host = $req->param('mosConfig_host');
my $mosConfig_sitename = $req->param('mosConfig_sitename');
my $mosConfig_user = $req->param('mosConfig_user');
my $mosConfig_password = $req->param('mosConfig_password');
my $mosConfig_db = $req->param('mosConfig_db');
my $installfolder = $req->param('installfolder');
my $dbused = $req->param('dbused');
my $copyfromdb = $req->param('copyfromdb');
if($destinationfolder && $sourcefolder){
$sourcedir = $rootdir ."/$sourcefolder";
$destinationdir = $rootdir . "/$destinationfolder";
if(!-e "$destinationdir" || $replacefolder){
$installfolder =~ s/\\/\//g;
my $locationofinstallationfolder;
if($installfolder =~ /\//i){
$locationofinstallationfolder = "$installfolder";
}else{
$configdir = $rootdir . "/$sourcefolder";
$locationofinstallationfolder = "$configdir/$installfolder";
}
if(-e "$locationofinstallationfolder"){
print "<p>Start Copy.........";
$cnt = 322;
$printfile = &getfolder($sourcedir);
print "<li>Total File : $totalfile\n";
print "<li>Total Folder : $totalfolder\n";
print "<p>Copy dirs...\n";
mkdir($destinationdir);
#foreach(@folders){
for(my $d=$#folders;$d>=0;$d--){
my $newdir =  $folders[$d];
$newdir =~ s/$sourcedir/$destinationdir/g;
print "<li>Copy $_ to $newdir...\n" if $showprogress;
if(!-e "$newdir"){
mkdir($newdir) or die "cannot make dir";
print " Done\n" if $showprogress;
}else{
print " Unchanged\n" if $showprogress;
}
}
print "<p>Copy Files....\n";
foreach(@files){
my $newfile =  $_;
$newfile =~ s/$sourcedir/$destinationdir/g;
print "<li>Copy $_ to $newfile ...\n" if $showprogress;
if((-e "$newfile" && $replacefile)||(!-e "$newfile")){
copy("$_","$newfile") or die "cannot copy file from $_ to $newfile";
print " Done\n" if $showprogress;
}else{
print " Unchanged\n" if $showprogress;
}
}
print "<p>Done";
if($doconfig){
print qq~
<p>Continue with Jooml Configuration 
<SCRIPT language=javascript>
location.href='?do=joomla&destinationfolder=$destinationfolder&dbused=$dbused&copyfromdb=$copyfromdb&mosConfig_host=$mosConfig_host&mosConfig_user=$mosConfig_user&mosConfig_password=$mosConfig_password&mosConfig_db=$mosConfig_db&installfolder=$locationofinstallationfolder&mosConfig_sitename=$mosConfig_sitename';
</SCRIPT>
~;
}
exit;
}else{
print qq~
<li>Installation Folder <b>$locationofinstallationfolder</b> doesn\'t exist
~;
}
}else{
print qq~
<li>Folder <b>$destinationdir</b> Already exist
~;
}
}else{
print qq~
<li>missing required fields
~;
}
exit;
}
sub getfolder{
$counter++;
my ($name) = @_;
my ${$counter};
opendir SUBDIR, "$name" or die "$name no exist";
@{$counter} = grep !/^\.\.?$/, readdir SUBDIR;
foreach (@{$counter}){
${$name} .= "\t$name/$_";
if(-d "$name/$_"){
${$name} .= " -> folder\n\t";
${$name} .= &getfolder("$name/$_");
$totalfolder = $totalfolder + 1;
push @folders,"$name/$_";
}
else{
if(-e "$name/$_"){
$cnt++;
#copy("$name/$_","$pubdir/$_");
my @filenames = split(/\./,$_);
my $justnames = $_;
$justnames =~ s/\.$filenames[$#filenames]//g;
#print "<li>$name/$_";
push @files,"$name/$_";
$totalfile = $totalfile + 1;
}
}
}
closedir SUBDIR;
return(${$name});
}
sub joomla{
my $destinationfolder = $req->param('destinationfolder');
$mosConfig_host = $req->param('mosConfig_host');
$mosConfig_sitename = $req->param('mosConfig_sitename');
$mosConfig_user = $req->param('mosConfig_user');
$mosConfig_password = $req->param('mosConfig_password');
$installfolder = $req->param('installfolder');
$mosConfig_db = $req->param('mosConfig_db');
$dbused = $req->param('dbused');
$copyfromdb = $req->param('copyfromdb');
if($destinationfolder){
$configdir = $rootdir . "/$destinationfolder";
$mosConfig_absolute_path = $configdir;
$mosConfig_cachepath = $rootdir . "/$destinationfolder/cache";
$mosConfig_live_site = "$rooturl/$destinationfolder";
$mosConfig_dbprefix = "jos_";
$mosConfig_mailfrom = $adminemail;
print "<p>Do Config..";
open(CONFIG,"$configdir/configuration.php");
my @configlines = <CONFIG>;
close CONFIG;
open(NEWCONFIG,">$configdir/configuration.php");
foreach(@configlines){
$_ =~ s/[\n\r]//g;
my ($var,$val) = split(/\=/,$_);
$var =~ s/\ //g;
$var =~ s/\$//g;
if(${$var}){
${$var} =~ s/\'/\\\'/g;
#print qq~<li>$var => ${$var}~;
print NEWCONFIG qq~\$$var = '${$var}';\n~;
}else{
#print qq~<li>Unchanged~;
print NEWCONFIG qq~$_\n~;
}
}
close NEWCONFIG;
print "..done";
if($dbused eq 'copy'){
print "<p>Copy Database from $copyfromdb to $mosConfig_db..";
my $new_db = "$mosConfig_db";
my $old_db = "$copyfromdb";
$dsn = "DBI:mysql:database=$old_db;host=localhost;port=3306";
$dbh = DBI->connect($dsn,$db_user,$db_password) or die $!;
my $sth = $dbh->prepare("show tables");
$sth->execute() or die qq|Database Error:  $DBI::errstr $query|;
while (my @rows =  $sth->fetchrow_array ){
push @tables,"$rows[0]";
}
$sth->finish;
$dbh->disconnect;
&doQuery("DROP DATABASE IF EXISTS  `$new_db` ;");
&doQuery("CREATE DATABASE `$new_db` ;");
$dsn = "DBI:mysql:database=$new_db;host=localhost;port=3306";
foreach(@tables){
if($_){
&doQuery("CREATE TABLE $new_db.$_ SELECT * FROM $old_db.$_");
}
}
}else{
print "<p>Do Primary Sql..";
open(SQL,"$installfolder/sql/joomla.sql");
my @sqllines = <SQL>;
close SQL;
my $joomlanewsql = '';
my $allsql = join('',@sqllines);
my @sqlcommand = split(/\;/,$allsql);
foreach(@sqlcommand){
#$_ =~ s/[\n\r]//g;
$_ =~ s/\#\_\_/$mosConfig_dbprefix/g;
push @joomlanewsql, "$_ ; ";
}
&doQuery("DROP DATABASE IF EXISTS  `$mosConfig_db` ;");
&doQuery("CREATE DATABASE `$mosConfig_db` ;");
$dsn = "DBI:mysql:database=$mosConfig_db;host=localhost;port=3306";
foreach(0..$#joomlanewsql - 1){
&doQuery("$joomlanewsql[$_]") if $joomlanewsql[$_];
}
my $usertable = $mosConfig_dbprefix.'users';
&doQuery("INSERT INTO `$usertable` VALUES (62, 'Administrator', 'admin', 'hairul\@onestop.com.my', '74b87337454200d4d33f80c4663dc5e5', 'Super Administrator', 0, 1, 25, '2007-05-07 11:25:36', '2007-05-07 11:26:21', '', 'expired=\nexpired_time=');");
print "..done";
print "<p>Do Samplae Data Sql..";
open(SQL,"$installfolder/sql/sample_data.sql");
my @sqllines = <SQL>;
close SQL;
my $joomlanewsql = '';
my $allsql = join('',@sqllines);
my @sqlcommand = split(/\;/,$allsql);
my @joomlanewsql;
foreach(@sqlcommand){
#$_ =~ s/[\n\r]//g;
$_ =~ s/\#\_\_/$mosConfig_dbprefix/g;
push @joomlanewsql, "$_ ; ";
}
foreach(0..$#joomlanewsql - 1){
&doQuery("$joomlanewsql[$_]") if $joomlanewsql[$_];
}
}
print "..done";
if(-e "$installfolder"){
rename ("$installfolder","$installfolder\-old") if $installfolder =~ /installation/i;
}
print qq~
<h1>Configuration Completed.</h1>
<a href="$mosConfig_live_site">click here to view ur website</a>
~;
}else{
print qq~
<li>missing folder
~;
}
exit;
}
sub dumps(){
my $new_db = "new_ajib";
my $old_db = "ajib";
$dsn = "DBI:mysql:database=$old_db;host=localhost;port=3306";
$dbh = DBI->connect($dsn,$db_user,$db_password) or die $!;
my $sth = $dbh->prepare("show tables");
$sth->execute() or die qq|Database Error:  $DBI::errstr $query|;
while (my @rows =  $sth->fetchrow_array ){
push @tables,"$rows[0]";
}
$sth->finish;
$dbh->disconnect;
&doQuery("DROP DATABASE IF EXISTS  `$new_db` ;");
&doQuery("CREATE DATABASE `$new_db` ;");
$dsn = "DBI:mysql:database=$new_db;host=localhost;port=3306";
print "<p>start ";
foreach(@tables){
if($_){
&doQuery("CREATE TABLE $new_db.$_ SELECT * FROM $old_db.$_");
print "<li>copy $new_db.$_ FROM $old_db.$_ ";
}
}
print "<p>done ";
}
sub doQuery{
my ($query) = @_;
$dbh = DBI->connect($dsn,$db_user,$db_password) or die $!;
# &sqlQuery($inserter);
$sth = $dbh->prepare($query) or die qq|Database Error: $DBI::errstr $query|;
# return &sqlerr("$DBI::errstr. <P>Query: $query");
  $sth->execute() or die qq|Database Error:  $DBI::errstr $query|;
$dbh->disconnect;
}
exit;
this is web base script. so just put this to ur cgi enable folder with 755 permission. 
u can simply modify certain area to suit ur preferences
**use at ur own risk.
happy coding.

No comments: