Location: PHPKode > projects > ChurchCMS > churchcms/install_mod.php
<?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:&nbsp;&nbsp;</td>" . 
	    "<td><b>{$module['name']}, version {$module['version']}</b></td></tr>" . 
	  "<tr><td width=\"25%\" align=\"right\">Author(s):&nbsp;&nbsp;</td>" . 
	    "<td><b>{$module['author']}</b></td></tr>" . 	  
	  "<tr><td width=\"25%\" align=\"right\">Description:&nbsp;&nbsp;</td>" . 
	    "<td><b>{$module['desc']}</b></td></tr>" . 	 
	  "<tr><td width=\"25%\" align=\"right\">Website:&nbsp;&nbsp;</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 &quot;Next&quot; 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 &quot;Next&quot; 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>&nbsp;(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);
	}
}

?>
Return current item: ChurchCMS