<?php
/**************************************************************************************************
* ChurchCMS
* Copyright (C) 2005 jsvoyager
*
* Developers & Contributors:
* jsvoyager hide@address.com
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software Foundation;
* either version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
* (license.txt)
***************************************************************************************************/
//We're not using the standard form here, so include only main.inc.php and not
// header.inc.php
include_once ("lib/main.inc.php");
//Set up error tracking because of all those @ used
ini_set("track_errors", "1");
//*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*
// AS SOON AS WE GOT USER AUTHENTACATION UP, CHECK TO SEE IF THEY'RE AN ADMIN HERE!!!!!!!
//*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*
//Include our tar reader
include ("lib/tar/Tar.php");
if ($_GET['step'] == 1 || !isset($_GET['step'])){
$_GET['step'] = 1;
//Open ARchive
$archive = new Archive_Tar($_REQUEST['file'], "gz");
//Get the files in it
if (($filelist = $archive->listContent()) == 0){
error (301, __FILE__, __LINE__, true, $_REQUEST['file']); //Unable to open archive
}
//Get our favorite file, module.def.php, from the archive and have it define our $module var
if (($module_def = $archive->extractInString("module.def.php")) == NULL){
error (320, __FILE__, __LINE__, true); //No module.def.php
}
$module_def = preg_replace ("/<\\?php/", "", $module_def);
$module_def = preg_replace ("/<\\?/", "", $module_def);
$module_def = preg_replace ("/\\?>/", "", $module_def);
if ( (@eval ($module_def)) === false){
error (321, __FILE__, __LINE__, true, $php_errormsg); //$module var definition not acceptable
}
if (!isset($module)){
error (321, __FILE__, __LINE__, true); //$module var not defined
}
//Have user confirm information
$content = "<p>You have chosen to install the " . $module['name'] . " module held within the " .$_REQUEST['file'].
" archive. The module has provided the following information about itself:</p><table border=\"0\">" .
"<tr><td width=\"25%\" align=\"right\">Name: </td>" .
"<td><b>{$module['name']}, version {$module['version']}</b></td></tr>" .
"<tr><td width=\"25%\" align=\"right\">Author(s): </td>" .
"<td><b>{$module['author']}</b></td></tr>" .
"<tr><td width=\"25%\" align=\"right\">Description: </td>" .
"<td><b>{$module['desc']}</b></td></tr>" .
"<tr><td width=\"25%\" align=\"right\">Website: </td>" .
"<td><b><a href=\"{$module['website']}\">{$module['website']}</a></b></td></tr>" .
"</table>";
//Show tables that will be installed.
//Get tables already in db
$result = $db->query(__FILE__, __LINE__, "SHOW TABLES FROM " . _DB_NAME_);
while($table = $db->results($result)){
$new_tables[] = $table[0];
}
$tables = $new_tables;
$content .= "<p>The following tables will be added to the database. Those already in the database are " .
"shown in yellow:</p><ul>";
foreach ($module['tables'] as $i => $table_info){
$content .= "<li";
if (in_array(_DB_PREFIX_.$table_info['name'], $tables, false)){
$content .= " class=\"warn\"";
}
$content .= ">" . $table_info['name'] . "</li>";
}
$content .= "</ul><p class=\"warn\">These tables -- and the data within them -- will be deleted if they already " .
"exsit in your database.</p>";
$content .= "<p>Are you sure you wish to install this module?</p>" .
"<p><a href=\"{$_SERVER['PHP_SELF']}?step=2\">Yes, please install the {$module['name']} module</a></p>";
$_SESSION['file'] = $_REQUEST['file'];
$_SESSION['module'] = $module;
//Continue on if we're being silent
if ($_GET['silent'] == true){
$_GET['step'] = 2;
}
}
if ($_GET['step'] == 2){
//And now the fun begins...actually installing!!!!!
$module = $_SESSION['module'];
/************************************
* Part I: Test for requirements
************************************/
$content = "<p class=\"title\">Requirements</p><table border=\"0\" width=\"75%\">" .
"<tr><td width=\"40%\"><b>Module Name</b></td><td width=\"15%\"><b>Needed</b></td><td><b>Have</b></td></tr>";
//First, we have to make sure our core is good
if ($module['requires'][0]['module'] != "CORE"){
error(322, __FILE__, __LINE__, true, "\$module['requires'][0]['module'] = \"CORE\"");
//Core version must be defined
}
$eval = "if (!(" . preg_replace("/\\./", "", _VERSION_) . " " . $module['requires'][0]['inequ'] . " " .
preg_replace("/\\./", "",$module['requires'][0]['version']) . ")){error(302, __FILE__, __LINE__, true);}";
eval ($eval);
$content .= "<tr><td><b>ChurchCMS CORE</b></td><td>{$module['requires'][0]['version']}</td>" .
"<td>" . _VERSION_ . "</td></tr>";
//Now for the various other requirements
for ($i=1; $i<count($module['requires']); $i++){
//Open up that module's definition file...
$required_mod_def = @file_get_contents("moduels/" . strtolower($module['requires'][$i]['module']) .
"module.def.php");
if ($required_mod_def === false){
error (303, __FILE__, __LINE__, true, $module['requires'][$i]['module']); //Module not installed
}
//...and see if version meets requirements
//Because our $module is getting overwriten, we must save a copy
$installing_mod = $module;
eval ($required_mod_def);
//Error info, just in case
$addinfo[] = $module['name'];
$addinfo[] = $installing_mod['requires'][$i]['version'];
$addinfo[] = $module['version'];
$eval = "if (!(" . preg_replace("/\\./", "", $module['version']) . " " . $module['requires'][1]['inequ'] .
" " . preg_replace("/\\./", "",$installing_mod['requires'][$i]['version']) .
")){error(302, __FILE__, __LINE__, true, \$addinfo);}";
eval ($eval);
$content .= "<tr><td><b>" . $installing_mod['requires'][$i]['module'] . "</b></td>" .
"<td>" . $installing_mod['requires'][$i]['version'] . "</td>" .
"<td>" . $module['version'] . "</td></tr>";
$module = $installing_mod;
}
$content .= "</table>";
//YEAH!! We meet all the requirements!!!
$content .= "<p class=\"good\">Minimum Requirements Satisfied</p>";
/************************************
* Part II: Implement DB Schema (ugh)
************************************/
$content .= "\n<p class=\"title\">SQL Database Schema Installation</p>";
//Go through each table and get it's field
for ($i=0; $i<count($module['tables']); $i++){
$query = "DROP TABLE IF EXISTS `" . _DB_PREFIX_ . $module['tables'][$i]['name'] . "`";
//Do the query
$db->query(__FILE__, __LINE__, $query);
$content .= "\n<pre>$query</pre>";
$query = "CREATE TABLE `" . _DB_PREFIX_ . $module['tables'][$i]['name'] . "`(\n";
//Now for the fields
for ($j=0; $j<count($module['tables'][$i]['fields']); $j++){
$query .= "\t`" . $module['tables'][$i]['fields'][$j]['dbname'] . "` " .
$module['tables'][$i]['fields'][$j]['type'] . " " . $module['tables'][$i]['fields'][$j]['addsql'] . ",\n";
}
//Remove that final "," and \n
$query = str_split($query, (strlen($query) - 2));
$query = $query[0];
//And some fianl ending stuff
$query .= "\n)";
//Do the query
$db->query(__FILE__, __LINE__, $query);
$content .= "\n<pre>$query</pre><br><br>\n";
//Add the database to the definition library file
$file = file(_ROOT_."/lib/tables.def.php");
$line_num = (count($file) - 3);
$file[$line_num] .= "\ndefine(\"_" . strtoupper($module['tables'][$i]['name']) . "_\", _DB_PREFIX_.\"" .
$module['tables'][$i]['name'] . "\");";
$fh = fopen(_ROOT_."/lib/tables.def.php", "w");
foreach ($file as $line){
fwrite($fh, $line);
}
}
//Yeah, db installed successfully
$content .= "\n<p class=\"good\">Database Schema Installed Successfully</p>";
/************************************
* Part IIIa: Prepare for file copy
************************************/
$content .= "<p class=\"title\">Pre-File Installation Test</p>";
$dir_name = strtolower($module['name']);
$warnings = "";
//See if module exsits
if (file_exists(_ROOT_ . "/modules/" . $dir_name)){
$warnings .= "<p class=\"warn\">WARNING: Module {$module['name']} appears to already exsist. " .
"By clicking "Next" below, you are acknowledging that you wish to overwrite the pre-exsisting " .
"module.</p>";
}
//See if we can write to module dir
if (!is_writable(_ROOT_ . "/modules/")){
$warnings .= "<p class=\"warn\">WARNING: The Module Installer does not appear to be able to write ".
"to the module direcotry (" ._ROOT_. "/modules/). Attempting to give the module installed write " .
"access...</p>";
if (!chmod(_ROOT_ . "/modules/", 0755)){
$warnings .= "<p class=\"warn\">WARNING: Unable to change the write permission of the module " .
"directory (" . _ROOT_ . "/modules/). Please change the permission manually before continuing " .
"the installation</p>";
}else{
$warnings .= "<p class=\"good\">Permission changed successfully. You may disregard the warning " .
"above about writing to the module directory.</p>";
}
}
//See if we can write to template dir
if (!is_writable(_ROOT_ . "/theme/templates/")){
$warnings .= "<p class=\"warn\">WARNING: The Module Installer does not appear to be able to write ".
"to the templates direcotry (" ._ROOT_. "/theme/templates/). Attempting to give the module installed" .
" write access...</p>";
if (!chmod(_ROOT_ . "/theme/templates/", 0755)){
$warnings .= "<p class=\"warn\">WARNING: Unable to change the write permission of the templates " .
"directory (" . _ROOT_ . "/theme/templates/). Please change the permission manually before continuing " .
"the installation</p>";
}else{
$warnings .= "<p class=\"good\">Permission changed successfully. You may disregard the warning " .
"above about writing to the template directory.</p>";
}
}
//See if we can write to the lang dir
if (!is_writable(_ROOT_ . "/lang/")){
$warnings .= "<p class=\"warn\">WARNING: The Module Installer does not appear to be able to write ".
"to the language direcotry (" ._ROOT_. "/lang/). Attempting to give the module installed" .
" write access...</p>";
if (!chmod(_ROOT_ . "/lang/", 0773)){
$warnings .= "<p class=\"warn\">WARNING: Unable to change the write permission of the language " .
"directory (" . _ROOT_ . "/lang/). Please change the permission manually before continuing " .
"the installation</p>";
}else{
$warnings .= "<p class=\"good\">Permission changed successfully. You may disregard the warning " .
"above about writing to the language directory.</p>";
}
}
if ($warnings == ""){
$content .= "<p>Variouis checks on your system have shown it fit for file installation. To install" .
" the module's files, please click "Next" below.</p>";
}else{
$content .= $warnings;
$content .= "<p>Please review the warnings above before proceeding with the installation.</p>";
}
$content .= "<a href=\"{$_SYSTEM['PHP_SELF']}?step=3\">Next</a> (This may take a while)";
//Continue on if we're being silent
if ($_GET['silent'] == true){
$_GET['step'] = 3;
}
}
if ($_GET['step'] == 3){
/************************************
* Part IIIb: Copy Files
************************************/
$module = $_SESSION['module'];
$archive = new Archive_Tar($_SESSION['file'], "gz");
$dir_name = strtolower($module['name']);
$content = "<p class=\"title\">Installing Files...</p>";
//Create main module directory
if (!@mkdir(_ROOT_ . "/modules/" . $dir_name, 0773)){
//More than likely it already exsits...let's just remove it
purgedir(_ROOT_ . "/modules/" . $dir_name);
//Now try to create it
if (!@mkdir(_ROOT_ . "/modules/" . $dir_name)){
error(300, __FILE__, __LINE__, true);
}
}
//Create theme directory
if (!@mkdir(_ROOT_ . "/theme/templates/" . $dir_name, 0773)){
//More than likely it already exsits...let's just remove it
purgedir(_ROOT_ . "/theme/templates/" . $dir_name);
//Now try to create it
if (!@mkdir(_ROOT_ . "/theme/templates/" . $dir_name)){
error(300, __FILE__, __LINE__, true);
}
}
//Extract files into it
if (!$archive->extract(_ROOT_ . "/modules/" . $dir_name)){
error(300, __FILE__, __LINE__, true);
}
$content .= "<p class=\"good\">Core Module Files Extracted Successfully</p>";
//Move template files....
copydircontents(_ROOT_ . "/modules/" . $dir_name . "/" . $module['templates'],
_ROOT_ . "/theme/templates/" . $dir_name, true);
$content .= "<p class=\"good\">Template Files Extracted Successfully</p>";
//Move the language files
foreach($module['lang'] as $lang_name => $dir){
if (!is_dir(_ROOT_ . "/lang/" . $lang_name)){
$content .= "<p class=\"warn\">Supported language $lang_name does not appear to be used in this" .
" ChurchCMS installation. Those language files were not installed.</p>";
purgedir(_ROOT_ . "/modules/" . $dir_name . "/" . $dir);
}else{
copydircontents(_ROOT_ . "/modules/" . $dir_name . "/" . $dir,
_ROOT_ . "/lang/" . strtolower($lang_name), true);
$content .= "<p class=\"good\">Language \"$lang_name\" installed successfully</p>";
}
}
//That's it, we're done!
$content .= "<p class=\"good\" align=\"center\"><b>Module Installed Successfully</b></p>";
$content .= "<a href=\"admin.php?op=post_mod_install\">Goto ChurchCMS Homepage</a>";
}
//////////////////////////////////////////////////////////////////////////
//Below this line is the html to show our module instilation procedure
//////////////////////////////////////////////////////////////////////////
if ($_GET['silent'] != true){
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=ISO-8859-1">
<link href="theme/theme.css" rel="stylesheet" type="text/css">
<style>
<!--
.warn {
color: yellow;
font-size: 110%;
}
.good {
color: green;
font-size: 110%;
}
-->
</style>
<title>Installing Module <?=$module['name']?></title>
</head>
<body>
<center>
<table class="subwindow" width="85%">
<tr><td class="title">Module Installation, Step <?=$_GET['step'] ?> of 3</td></tr>
<tr><td class="body">
<?=$content?>
</td></tr>
</table>
</center>
</body>
</html>
<?
}
function purgedir($dir){
$handle = opendir($dir);
while (false !== ($file = readdir($handle))){
if ($file != "." && $file != ".."){
if (is_dir("$dir/$file")){
purgedir ("$dir/$file");
}else{
unlink("$dir/$file");
}
}
}
closedir($handle);
rmdir($dir);
}
function copydircontents($dir, $to, $move = false){
$handle = @opendir($dir) or error(323, __FILE__, __LINE__, true, $dir);
while (false !== ($file = readdir($handle))){
if ($file != "." && $file != ".."){
if (is_dir("$dir/$file")){
copydircontents("$dir/$file", "$to/$file");
if ($move == true){
purgedir ("$dir/$file");
}
}else{
copy("$dir/$file", "$to/$file");
if ($move==true){
unlink("$dir/$file");
}
}
}
}
closedir($handle);
if ($move==true){
rmdir($dir);
}
}
?>