<?php
// $Id: installer_common.php,v 1.44 2003/12/19 23:20:48 saka_car Exp $
/**
* Installer Common code
* @package Mambo Open Source
* @Copyright (C) 2000 - 2003 Miro International Pty Ltd
* @ All rights reserved
* @ Mambo Open Source is Free Software
* @ Released under GNU/GPL License : http://www.gnu.org/copyleft/gpl.html
* @version $Revision: 1.44 $
**/

defined( '_VALID_MOS' ) or die( 'Direct Access to this location is not allowed.' );

// Common functions for the installer(s)
// Extract functions
require_once( "$mosConfig_absolute_path/administrator/classes/pclzip.lib.php" );
require_once( "$mosConfig_absolute_path/administrator/classes/pclerror.lib.php" );
require_once( "$mosConfig_absolute_path/administrator/classes/pcltrace.lib.php" );
require_once( "$mosConfig_absolute_path/administrator/classes/pcltar.lib.php" );

// XML library
require_once( "$mosConfig_absolute_path/administrator/classes/minixml/minixml.inc.php" );

// Correct mask
@umask(0);

/**
* Component database table class
*/
class mosComponent extends mosDBTable {
	/** @var int Primary key */
	var $id=null;
	/** @var string */
	var $name=null;
	/** @var string */
	var $link=null;
	/** @var int */
	var $menuid=null;
	/** @var int */
	var $parent=null;
	/** @var string */
	var $admin_menu_link=null;
	/** @var string */
	var $admin_menu_alt=null;
	/** @var string */
	var $option=null;
	/** @var string */
	var $ordering=null;
	/** @var string */
	var $admin_menu_img=null;
	/** @var int */
	var $is_core=null;

	/**
	* @param database A database connector object
	*/
	function mosComponent( &$db ) {
		$this->mosDBTable( '#__components', 'id', $db );
	}
}

//
// Base class for the installer
//
class mosInstaller
{
	// name of the XML file with installation information
	var $i_installfilename	= "";
	var $i_installarchive	= "";
	var $i_installdir		= "";
	var $i_iswin			= false;
	var $i_errno			= 0;
	var $i_error			= "";
	var $i_installtype		= "";
	var $i_unpackdir		= "";
	var $i_docleanup		= true;

	// XML documet
	var $i_xmldoc			= null;

	//
	// Let the show begin...
	//
	function mosInstaller($p_filename = null, $p_unpack = true)
	{
		$this->i_iswin = (substr(PHP_OS, 0, 3) == 'WIN' && stristr ( $_SERVER["SERVER_SOFTWARE"], "microsoft"));
		$this->installArchive($p_filename);
		if($p_unpack)
		{
			if($this->extractArchive())
			{
				$this->findInstallFile();
			}
		}
	}

	function findInstallFile()
	{
		$installfilefound = false;
		// Try to find the package XML file
		$filesindir = mosReadDirectory( $this->installDir() ,".xml");
		if(count($filesindir) > 0)
		{
			foreach($filesindir as $file)
			{
				$packagefile = $this->isPackageFile($this->installDir() . $file);
				if(!is_null($packagefile) && !$installfilefound )
				{
					$this->xmlDoc($packagefile);
					return true;
				}
			}
		}
		else
		{
			return false;
		}
	}

	function pathName($p_path)
	{
		$retval = "";

		if($this->isWindows())
		{
			$retval = str_replace('/','\\',$p_path);
			if(substr($retval,-1) != '\\')
			$retval .= '\\';

			// Remove double \\
			$retval = str_replace('\\\\','\\',$retval);
		}
		else
		{
			$retval = str_replace('\\','/',$p_path);
			if(substr($retval,-1) != '/')
			$retval .= '/';

			// Remove double //
			$retval = str_replace('//','/',$retval);
		}

		return $retval;
	}

	function isPackageFile($p_file)
	{

		$xmlDoc = new MiniXMLDoc();
		$xmlDoc->fromFile($p_file);
		$ismosinstall = & $xmlDoc->getElementByPath('mosinstall');
		if($ismosinstall)
		{
			// Set the type
			$this->installType($ismosinstall->attribute("type"));
			$this->installFilename($p_file);
			return $xmlDoc;
		}
		return null;
	}

	function xmlDoc($p_xmldoc = null)
	{
		if(!is_null($p_xmldoc)) {
			$this->i_xmldoc = $p_xmldoc;
		}

		return $this->i_xmldoc;
	}
	function installArchive($p_filename = null)
	{
		if(!is_null($p_filename))
		$this->i_installarchive = $p_filename;

		return $this->i_installarchive;
	}

	function installFilename($p_filename = null)
	{
		if(!is_null($p_filename))
		{
			if($this->isWindows())
			{
				$this->i_installfilename = str_replace('/','\\',$p_filename);
			}
			else
			{
				$this->i_installfilename = str_replace('\\','/',$p_filename);
			}
		}

		return $this->i_installfilename;
	}

	function installDir($p_dirname = null)
	{
		if(!is_null($p_dirname))
		{
			$this->i_installdir = $this->pathName($p_dirname);
		}
		return $this->i_installdir;
	}

	function unpackDir($p_dirname = null)
	{
		if(!is_null($p_dirname))
		{
			$this->i_unpackdir = $this->pathName($p_dirname);
		}
		return $this->i_unpackdir;
	}

	//
	// Install method MUST be overridden
	//
	function install()
	{
		die("Hmm... someone forget to make the install method..");
	}

	function isWindows()
	{
		return $this->i_iswin;
	}

	function errno($p_errno = null)
	{
		if(!is_null($p_errno))
		$this->i_errno = $p_errno;

		return $this->i_errno;
	}

	function error($p_error = null)
	{
		if(!is_null($p_error))
		$this->i_error = $p_error;

		return $this->i_error;
	}

	function setError($p_errno, $p_error)
	{
		$this->errno($p_errno);
		$this->error($p_error);
	}

	function getError($p_full = false)
	{
		if($p_full)
		{
			return $this->errno() . " " . $this->error();
		}
		else
		{
			return $this->error();
		}
	}

	//
	// copyFiles
	// Arguments:
	// $p_sourceir	: Source directory
	// $p_destdir	: Destination directory
	// $p_files		: array with filenames
	//
	function copyFiles($p_sourcedir, $p_destdir, $p_files)
	{
		if(is_array($p_files) && count($p_files) > 0)
		{
			foreach($p_files as $_file)
			{
				$filesource	= $this->pathName($p_sourcedir) . $_file;
				$filedest	= $this->pathName($p_destdir) . $_file;
				if($this->isWindows())
				{
					$filesource = str_replace('/','\\',$filesource);
					$filedest	= str_replace('/','\\',$filedest);
				}
				else
				{
					$filesource = str_replace('\\','/',$filesource);
					$filedest	= str_replace('\\','/',$filedest);
				}

				if(file_exists($filesource))
				{
					if(!(copy($filesource,$filedest) && chmod($filedest, 0777)))
					{
						$this->setError(1,"Failed to copy file: $filesource to $filedest");
						return false;
					}
				}
				else
				{
					$this->setError(1,"File $filesource does not exist!");
					return false;
				}
			}
		}
		else
		{
			return false;
		}
		return true;
	}

	//
	// readInstallFile
	//
	function readInstallFile()
	{
		if($this->installFilename() == "")
		{
			$this->setError(1,"No filename specified");
			return false;
		}

		$this->i_xmldoc = new MiniXMLDoc();
		$this->i_xmldoc->fromFile($this->installFilename());

		// Check that it's a installation file
		$main_element = &$this->i_xmldoc->getElementByPath('mosinstall');
		if(!$main_element)
		{
			$this->setError(1,"File :'" . $this->installFilename() . "' is not a valid MOS installation file");
			return false;
		}

		$this->installType($main_element->attribute("type"));
		return true;
	}

	//
	// Installation type
	//
	function installType($p_installtype = null)
	{
		if(!is_null($p_installtype))
		$this->i_installtype = $p_installtype;

		return $this->i_installtype;
	}

	function extractArchive()
	{
		global $mosConfig_absolute_path;
		$base_Dir = $this->pathName($mosConfig_absolute_path . "/uploadfiles/");

		$archivename	= $base_Dir . $this->installArchive();
		$tmpdir			= uniqid("install_");

		if($this->isWindows())
		{
			$extractdir	= str_replace('/','\\',$this->pathName($base_Dir . "$tmpdir"));
			$archivename = str_replace('/','\\',$archivename);
		}
		else
		{
			$extractdir	= str_replace('\\','/',$this->pathName($base_Dir . "$tmpdir"));
			$archivename = str_replace('\\','/',$archivename);
		}

		$this->unpackDir($extractdir);
		// Find the extension of the file
		$fileext = substr(strrchr(basename($this->installArchive()), '.'), 1);
		if($fileext == "gz" || $fileext == "tar")
		{
			PclTarExtract($archivename,$extractdir);
			if(PclErrorCode() != 1)
			{
				HTML_installer::showInstallMessage(PclErrorString(),"Upload new Component -  error",$option);
				TrDisplay();
				exit();
			}
			$this->installDir($extractdir);
		}
		else
		{
			$zipfile = new PclZip($archivename);
			if($this->isWindows()) {
				define('OS_WINDOWS',1);
			} else {
				define('OS_WINDOWS',0);
			}

			$ret = $zipfile->extract(PCLZIP_OPT_PATH,$extractdir);
			if($ret == 0)
			{
				$this->setError(1,"Unrecoverable error '".$zipfile->errorName(true)."'","Upload new Component -  error",$option);
				return false;
			}
			$this->installDir($extractdir);
		}

		// Try to find the correct install dir. in case that the package have subdirs
		// Save the install dir for later cleanup
		$filesindir = mosReadDirectory( $this->installDir() ,"");
		if(count($filesindir) == 1)
		{
			if(is_dir($extractdir . $filesindir[0]))
			{
				$this->installDir($extractdir . $filesindir[0]);
			}
		}
		return true;
	}
}

//
// Component installer
//

class mosInstallerComponent extends mosInstaller
{
	var $i_componentdir		= "";
	var $i_componentadmindir	= "";
	var $i_componentname		= "";
	var $i_hasinstallfile		= false;
	var $i_installfile		= "";

	function mosInstallerComponent($p_filename = null,$p_unpack = true)
	{
		global $mosConfig_absolute_path;
		parent::mosInstaller($p_filename,$p_unpack);
	}

	function componentDir($p_dirname = null)
	{
		if(!is_null($p_dirname))
		{
			$this->i_componentdir = $this->pathName($p_dirname);
		}
		return $this->i_componentdir;
	}

	function componentAdminDir($p_dirname = null)
	{
		if(!is_null($p_dirname))
		{
			$this->i_componentadmindir = $this->pathName($p_dirname);
		}
		return $this->i_componentadmindir;
	}

	function componentName($p_name = null)
	{
		if(!is_null($p_name))
		{
			$this->i_componentname = $p_name;
		}
		return $this->i_componentname;
	}

	function hasInstallfile($p_hasinstallfile = null)
	{
		if(!is_null($p_hasinstallfile))
		{
			$this->i_hasinstallfile = $p_hasinstallfile;
		}
		return $this->i_hasinstallfile;
	}
	function installfile($p_installfile = null)
	{
		if(!is_null($p_installfile))
		{
			$this->i_installfile = $p_installfile;
		}
		return $this->i_installfile;
	}

	//
	// Component installation
	//
	function install($p_fromdir = null)
	{
		global $mosConfig_absolute_path,$database;

		if(!is_null($p_fromdir))
		{
			$this->installDir($p_fromdir);
		}

		// added by aje for install from directory
		if (!$this->installfile()) {
			$this->findInstallFile();
		}

		if(!$this->readInstallFile())
		{
			$this->setError(1,"Installation file not found: <br>" . $this->installDir());
			return false;
		}

		if($this->installType() != "component")
		{
			$this->setError(1,"Installation file is not a component installation file");
			return false;
		}

		// In case there where an error doring reading or extracting the archive
		if($this->errno())
		{
			return false;
		}

		// aje moved down to here. ??  seemed to be some referencing problems
		$xml = $this->xmlDoc();

		// Set some vars
		$e = &$xml->getElementByPath('mosinstall/name');
		$this->componentName($e->getValue());
		$this->componentDir($mosConfig_absolute_path . "/components/" . strtolower("com_" . str_replace(" ","",$this->componentName())) . "/");
		$this->componentAdminDir($mosConfig_absolute_path . "/administrator/components/" . strtolower("com_" . str_replace(" ","",$this->componentName())));

		if(!file_exists($this->componentDir()) && !mkdir($this->componentDir(),0777))
		{
			$this->setError(1,"Failed to create directory'" . $this->componentDir() . "'");
			return false;
		}

		if(!file_exists($this->componentAdminDir()) && !mkdir($this->componentAdminDir(),0777))
		{
			$this->setError(1,"Failed to create directory'" . $this->componentAdminDir() . "'");
			return false;
		}


		// Find files to copy
		$files_element = &$xml->getElementByPath('mosinstall/files');
		if(is_null($files_element))
		{
			$this->setError(1,"No files found to copy");
			return false;
		}

		$component_files = $files_element->getAllChildren();
		$copyfiles = array();
		foreach($component_files as $component_file)
		{
			if(basename($component_file->getValue()) != $component_file->getValue())
			{
				$newdir = dirname($component_file->getValue());
				if(!file_exists($this->componentDir() . "$newdir") && !mkdir($this->componentDir() . "$newdir",0777))
				{
					$this->setError(1,"Failed to create directory'" . $this->componentDir() . "$newdir" . "'");
					return false;
				}
			}
			$copyfiles[] = $component_file->getValue();
		}

		if(!$this->copyFiles($this->installDir(), $this->componentDir(), $copyfiles))
		{
			return false;
		}
		// Is there any images?
		$files_element = &$xml->getElementByPath('mosinstall/images');
		if(!is_null($files_element))
		{
			$component_files = $files_element->getAllChildren();
			$copyfiles = array();

			foreach($component_files as $component_file)
			{
				if(basename($component_file->getValue()) != $component_file->getValue())
				{
					$newdir = dirname($component_file->getValue());
					if(!file_exists($this->componentDir() . "$newdir") && !mkdir($this->componentDir() . "$newdir",0777))
					{
						$this->setError(1,"Failed to create directory'" . $this->componentDir() . "$newdir" . "'");
						return false;
					}
				}

				$copyfiles[] = $component_file->getValue();
			}

			if(!$this->copyFiles($this->installDir(), $this->componentDir(), $copyfiles))
			{
				$this->setError(1,"Could not copy image files");
				return false;
			}
		}

		// find administrator files
		$files_element = &$xml->getElementByPath('mosinstall/administration/files');
		if(!is_null($files_element))
		{
			$component_files = $files_element->getAllChildren();
			$copyfiles = array();
			foreach($component_files as $component_file)
			{
				if(basename($component_file->getValue()) != $component_file->getValue())
				{
					$newdir = dirname($component_file->getValue());
					if(!file_exists($this->componentAdminDir() . "$newdir") && !mkdir($this->componentAdminDir() . "$newdir",0777))
					{
						$this->setError(1,"Failed to create directory'" . $this->componentAdminDir() . "$newdir" . "'");
						return false;
					}
				}
				$copyfiles[] = $component_file->getValue();
			}

			if(!$this->copyFiles($this->installDir(), $this->componentAdminDir(), $copyfiles))
			{
				$this->setError(1,"Could not copy administrator files");
				return false;
			}
		}
		// Is there any images?
		$files_element = &$xml->getElementByPath('mosinstall/administration/images');
		if(!is_null($files_element))
		{
			$component_files = $files_element->getAllChildren();
			$copyfiles = array();
			foreach($component_files as $component_file)
			{
				if(basename($component_file->getValue()) != $component_file->getValue())
				{
					$newdir = dirname($component_file->getValue());
					if(!file_exists($this->componentAdminDir() . "$newdir") && !mkdir($this->componentAdminDir() . "$newdir",0777))
					{
						$this->setError(1,"Failed to create directory'" . $this->componentAdminDir() . "$newdir" . "'");
						return false;
					}
				}

				$copyfiles[] = $component_file->getValue();
			}

			if(!$this->copyFiles($this->installDir(), $this->componentAdminDir(), $copyfiles))
			{
				$this->setError(1,"Could not copy administrator image files");
				return false;
			}
		}

		// Copy the XML - we should use it during uninstall
		if(!$this->copyFiles($this->installDir(), $this->componentAdminDir(), array(basename($this->installFilename()))))
		{
			$this->setError(1,"Could not copy installation XML file");
			return false;
		}

		// Are there any SQL queries??
		$query_element = &$xml->getElementByPath('mosinstall/install/queries');
		if(!is_null($query_element))
		{
			$queries = $query_element->getAllChildren();
			foreach($queries as $query)
			{
				$database->setQuery( $query->getValue());
				if (!$database->query())
				{
					$this->setError(1,"SQL Error " . $database->stderr(true),"Upload new Component -  error");
					return false;
				}
			}
		}

		// Is there an installfile
		$installfile_elemet = &$xml->getElementByPath('mosinstall/installfile');
		if(!is_null($installfile_elemet))
		{
			if(!$this->copyFiles($this->installDir(), $this->componentAdminDir(), array($installfile_elemet->getValue())))
			{
				$this->setError(1,"Could not copy installation file");
				return false;
			}
			$this->hasInstallfile(true);
			$this->installFile($installfile_elemet->getValue());
		}
		// Is there an uninstallfile
		$uninstallfile_elemet = &$xml->getElementByPath('mosinstall/uninstallfile');
		if(!is_null($uninstallfile_elemet))
		{
			if(!$this->copyFiles($this->installDir(), $this->componentAdminDir(), array($uninstallfile_elemet->getValue())))
			{
				$this->setError(1,"Could not copy uninstall file");
				return false;
			}
		}

		// Is the menues ?
		$adminmenu_element = &$xml->getElementByPath('mosinstall/administration/menu');
		if(!is_null($adminmenu_element))
		{
			$adminsubmenu_element	= &$xml->getElementByPath('mosinstall/administration/submenu');
			$com_name				= strtolower("com_" . str_replace(" ","",$this->componentName()));
			$com_admin_menuname		= $adminmenu_element->getValue();

			if(!is_null($adminsubmenu_element))
			{
				$com_admin_menu_id	= $this->createParentMenu($com_admin_menuname,$com_name);
				if($com_admin_menu_id === false)
				{
					return false;
				}
				$com_admin_submenus = $adminsubmenu_element->getAllChildren();

				$submenuordering = 0;
				foreach($com_admin_submenus as $admin_submenu)
				{
					$com = new mosComponent( $database );
					$com->name		= $admin_submenu->getvalue();
					$com->link		= '';
					$com->menuid	= 0;
					$com->parent	= $com_admin_menu_id;
					$com->iscore	= 0;

					if ( $admin_submenu->attribute("act"))
					{
						$com->admin_menu_link = "option=$com_name&act=" . $admin_submenu->attribute("act");
					}
					else if ($admin_submenu->attribute("task"))
					{
						$com->admin_menu_link = "option=$com_name&task=" . $admin_submenu->attribute("task");
					}
					else if ($admin_submenu->attribute("link"))
					{
						$com->admin_menu_link = $admin_submenu->attribute("link");
					}
					else
					{
						$com->admin_menu_link = "option=$com_name";
					}
					$com->admin_menu_alt = $admin_submenu->getValue();
					$com->option = $com_name;
					$com->ordering = $submenuordering++;
					$com->admin_menu_img = "js/ThemeOffice/component.png";

					if (!$com->store())
					{
						$this->setError(1,$database->stderr(true));
						return false;
					}
				}
			}
			else
			{
				$this->createParentMenu($com_admin_menuname,$com_name);
			}
		}

		if($this->hasInstallfile())
		{
			require_once($this->componentAdminDir() . "/" . $this->installFile());
			$ret = com_install();
			if($ret != "");
			{
				$this->setError(0,$ret);
			}
		}

		return true;
	}

	function createParentMenu($_menuname,$_comname, $_image = "js/ThemeOffice/component.png")
	{
		global $database;
		$db_name		= $_menuname;
		$db_link		= "option=$_comname";
		$db_menuid		= 0;
		$db_parent		= 0;
		$db_admin_menu_link	= "option=$_comname";
		$db_admin_menu_alt	= $_menuname;
		$db_option		= $_comname;
		$db_ordering		= 0;
		$db_admin_menu_img	= $_image;
		$db_iscore		= 0;

		$sql = "INSERT INTO #__components ";
		$sql .=" VALUES('','$db_name','$db_link','$db_menuid','$db_parent','$db_admin_menu_link','$db_admin_menu_alt','$db_option','$db_ordering','$db_admin_menu_img',$db_iscore)";
		$database->setQuery($sql);
		if(!$database->query())
		{
			$this->setError(1,$database->stderr(true));
			return false;
		}
		$menuid = $database->insertid();
		return $menuid;
	}
}

//
// Module installer
//
class mosInstallerModule extends mosInstaller
{
	var $i_moduledir		= "";
	var $i_modulename		= "";
	var $i_moduledb			= "";

	function mosInstallerModule($p_filename = null)
	{
		parent::mosInstaller($p_filename);
	}

	function moduleDir($p_dirname = null)
	{
		if(!is_null($p_dirname))
		{
			$this->i_moduledir = $this->pathName($p_dirname);
		}
		return $this->i_moduledir;
	}

	function moduleDB($p_name = null)
	{
		if(!is_null($p_name))
		{
			$this->i_moduledb = $p_name;
		}
		return $this->i_moduledb;
	}

	function moduleName($p_name = null)
	{
		if(!is_null($p_name))
		{
			$this->i_modulename = $p_name;
		}
		return $this->i_modulename;
	}

	//
	// Module installation
	//
	function install()
	{
		global $mosConfig_absolute_path,$database;

		$xml = $this->xmlDoc();

		if(!$this->readInstallFile())
		{
			$this->setError(1,"Installation file not found");
			return false;
		}

		if($this->installType() != "module")
		{
			$this->setError(1,"Installation file is not a module installation file");
			return false;
		}

		// In case there where an error doring reading or extracting the archive
		if($this->errno())
		{
			return false;
		}

		// Set some vars
		$e = &$xml->getElementByPath('mosinstall/name');
		$this->moduleName($e->getValue());
		$this->moduleDir($mosConfig_absolute_path . "/modules/");

		// Find files to copy
		$files_element = &$xml->getElementByPath('mosinstall/files');
		if(is_null($files_element))
		{
			$this->setError(1,"No files found to copy");
			return false;
		}
		else
		{
			$module_files = $files_element->getAllChildren();
			$copyfiles = array();
			foreach($module_files as $module_file)
			{
				if(basename($module_file->getValue()) != $module_file->getValue())
				{
					$newdir = dirname($module_file->getValue());
					if(!file_exists($this->moduleDir() . "$newdir") && !mkdir($this->moduleDir() . "$newdir",0777))
					{
						$this->setError(1,"Failed to create directory'" . $this->moduleDir() . "$newdir" . "'");
						return false;
					}
				}
				$copyfiles[] = $module_file->getValue();
				// check for attribute
				if(!is_null($module_file->attribute("module")))
				{
					$this->moduleDB($module_file->attribute("module"));
				}

			}
			if($this->moduleDB() == "")
			{
				$this->setError(1,"No file is marked as module file");
				return false;
			}

			if(!$this->copyFiles($this->installDir(), $this->moduleDir(), $copyfiles))
			{
				$this->setError(1,"Could not copy module files");
				return false;
			}
		}

		// Is there any images?
		$files_element = &$xml->getElementByPath('mosinstall/images');
		if(!is_null($files_element))
		{
			$module_files = $files_element->getAllChildren();
			$copyfiles = array();
			foreach($module_files as $module_file)
			{
				if(basename($module_file->getValue()) != $module_file->getValue())
				{
					$newdir = dirname($module_file->getValue());
					if(!file_exists($this->moduleDir() . "$newdir") &&!mkdir($this->moduleDir() . "$newdir",0777))
					{
						$this->setError(1,"Failed to create directory'" . $this->moduleDir() . "$newdir" . "'");
						return false;
					}
				}

				$copyfiles[] = $module_file->getValue();
			}

			if(!$this->copyFiles($this->installDir(), $this->moduleDir(), $copyfiles))
			{
				$this->setError(1,"Could not copy image files");
				return false;
			}
		}

		// Insert in module in DB
		$database->setQuery( "SELECT id FROM #__modules WHERE module = '" . $this->moduleDB() . "'" );
		if(!$database->query())
		{
			$this->setError(1,"SQL error: " . $database->stderr(true));
			return false;
		}

		$id = $database->loadResult();

		if (!$id)
		{
			$row = new mosModule( $database );
			$row->title = $this->moduleName();
			$row->ordering = 99;
			$row->position = 'left';
			$row->showtitle = 1;
			$row->module = $this->moduleDB();

			$row->store();

			$database->setQuery( "INSERT INTO #__modules_menu VALUES ('$row->id', 0)" );
			if(!$database->query())
			{
				$this->setError(1,"SQL error: " . $database->stderr(true));
				return false;
			}
		}
		else
		{
			$this->setError(1,"Module '" . $this->moduleName() . "' already exists!");
			return false;
		}

		return true;
	}
}

//
// Template installer
//
class mosInstallerTemplate extends mosInstaller
{
	var $i_templatedir		= "";
	var $i_templatename		= "";

	function mosInstallerTemplate($p_filename)
	{
		parent::mosInstaller($p_filename);
	}

	function templateDir($p_dirname = null)
	{
		if(!is_null($p_dirname))
		{
			$this->i_templatedir = $this->pathName($p_dirname);
		}
		return $this->i_templatedir;
	}

	function templateName($p_name = null)
	{
		if(!is_null($p_name))
		{
			$this->i_templatename = $p_name;
		}
		return $this->i_templatename;
	}

	//
	// Template installation
	//
	function install()
	{
		global $mosConfig_absolute_path,$database;

		$xml = $this->xmlDoc();

		if(!$this->readInstallFile())
		{
			$this->setError(1,"Installation file not found!");
			return false;
		}

		if($this->installType() != "template")
		{
			$this->setError(1,"Installation file is not a template installation file");
			return false;
		}

		// In case there where an error doring reading or extracting the archive
		if($this->errno())
		{
			return false;
		}

		// Set some vars
		$e = &$xml->getElementByPath('mosinstall/name');
		$this->templateName($e->getValue());
		$this->templateDir($mosConfig_absolute_path . "/templates/" . strtolower(str_replace(" ","_",$this->templateName())));
		if(!file_exists($this->templateDir()) && !mkdir($this->templateDir(),0777))
		{
			$this->setError(1,"Failed to create directory'" . $this->templateDir() . "'");
			return false;
		}

		// Find files to copy
		$files_element = &$xml->getElementByPath('mosinstall/files');
		if(is_null($files_element))
		{
			$this->setError(1,"No files found to copy");
			return false;
		}

		$template_files = $files_element->getAllChildren();
		$copyfiles = array();
		foreach($template_files as $template_file)
		{
			if(basename($template_file->getValue()) != $template_file->getValue())
			{
				$newdir = dirname($template_file->getValue());
				if(!file_exists($this->templateDir() . "$newdir") && !mkdir($this->templateDir() . "$newdir",0777))
				{
					$this->setError(1,"Failed to create directory'" . $this->templateDir() . "$newdir" . "'");
					return false;
				}
			}
			$copyfiles[] = $template_file->getValue();
		}

		if(!$this->copyFiles($this->installDir(), $this->templateDir(), $copyfiles))
		{
			return false;
		}

		// Is there any images?
		$files_element = &$xml->getElementByPath('mosinstall/images');
		if(!is_null($files_element))
		{
			$template_files = $files_element->getAllChildren();
			$copyfiles = array();
			foreach($template_files as $template_file)
			{
				if(basename($template_file->getValue()) != $template_file->getValue())
				{
					$newdir = dirname($template_file->getValue());
					if(!file_exists($this->templateDir() . "$newdir") && !mkdir($this->templateDir() . "$newdir",0777))
					{
						$this->setError(1,"Failed to create directory'" . $this->templateDir() . "$newdir" . "'");
						return false;
					}
				}
				$copyfiles[] = $template_file->getValue();
			}

			if(!$this->copyFiles($this->installDir(), $this->templateDir(), $copyfiles))
			{
				return false;
			}
		}
		// Is there any css?
		$files_element = &$xml->getElementByPath('mosinstall/css');
		if(!is_null($files_element))
		{
			$css_files = $files_element->getAllChildren();
			$copyfiles = array();
			foreach($css_files as $css_file)
			{
				if(basename($css_file->getValue()) != $css_file->getValue())
				{
					$newdir = dirname($css_file->getValue());
					if(!file_exists($this->templateDir() . "$newdir") && !mkdir($this->templateDir() . "$newdir",0777))
					{
						$this->setError(1,"Failed to create directory'" . $this->templateDir() . "$newdir" . "'");
						return false;
					}
				}

				$copyfiles[] = $css_file->getValue();
			}

			if(!$this->copyFiles($this->installDir(), $this->templateDir(), $copyfiles))
			{
				return false;
			}
		}

		// Copy the XML - we should use it during uninstall
		if(!$this->copyFiles($this->installDir(), $this->templateDir(), array(basename($this->installFilename()))))
		{
			return false;
		}

		return true;
	}
}

// Code below will be deleted
function uploadFile( $filename, $userfile_name, $option, &$msg )
{
	global $mosConfig_absolute_path,$SERVER_SOFTWARE;
	$base_Dir = "$mosConfig_absolute_path/uploadfiles/";

	if (!is_writable( $base_Dir )) {
		$msg = '<p><span style="color:#ff0000">/uploadfiles</span> directory is not writable.'
		. ' Cannot upload file to server.</p>';
		return false;
	}

	if (!(move_uploaded_file($filename, $base_Dir . $userfile_name) && chmod($base_Dir . $userfile_name, 0777)))
	{
		return false;
	}
	return true;
}

//
// Language installer
//
class mosInstallerLanguage extends mosInstaller
{
	var $i_languagedir		= "";
	var $i_languagename		= "";

	function mosInstallerLanguage($p_filename = null)
	{
		parent::mosInstaller($p_filename);
	}

	function languageDir($p_dirname = null)
	{
		if(!is_null($p_dirname))
		{
			$this->i_languagedir = $this->pathName($p_dirname);
		}
		return $this->i_languagedir;
	}

	function languageName($p_name = null)
	{
		if(!is_null($p_name))
		{
			$this->i_languagename = $p_name;
		}
		return $this->i_languagename;
	}

	//
	// Language installation
	//
	function install()
	{
		global $mosConfig_absolute_path,$database;

		$xml = $this->xmlDoc();

		if(!$this->readInstallFile())
		{
			$this->setError(1,"Installation file is not found");
			return false;
		}

		if($this->installType() != "language")
		{
			$this->setError(1,"Installation file is not a language installation file");
			return false;
		}

		// In case there where an error doring reading or extracting the archive
		if($this->errno())
		{
			return false;
		}

		// Set some vars
		$e = &$xml->getElementByPath('mosinstall/name');
		$this->languageName($e->getValue());
		$this->languageDir($mosConfig_absolute_path . "/language/");

		// Find files to copy
		$files_element = &$xml->getElementByPath('mosinstall/files');
		if(is_null($files_element))
		{
			$this->setError(1,"No files found to copy");
			return false;
		}
		else
		{
			$language_files = $files_element->getAllChildren();
			$copyfiles = array();
			foreach($language_files as $language_file)
			{
				if(basename($language_file->getValue()) != $language_file->getValue())
				{
					$newdir = dirname($language_file->getValue());
					if(!file_exists($this->languageDir() . "$newdir") && !mkdir($this->languageDir() . "$newdir",0777))
					{
						$this->setError(1,"Failed to create directory'" . $this->languageDir() . "$newdir" . "'");
						return false;
					}
				}
				$copyfiles[] = $language_file->getValue();
				// check for attribute
				if(!is_null($language_file->attribute("language")))
				{
					$this->languageDB($language_file->attribute("language"));
				}

			}

			if(!$this->copyFiles($this->installDir(), $this->languageDir(), $copyfiles))
			{
				$this->setError(1,"could not copy language files");
				return false;
			}
		}

		return true;
	}
}

function cleanupInstall($userfile_name,$resultdir)
{
	global $mosConfig_absolute_path;
	if(file_exists($resultdir))
	{
		deldir($resultdir);
		unlink($mosConfig_absolute_path . "/uploadfiles/$userfile_name");
	}
}
function deldir($dir) {
	$current_dir = opendir($dir);
	while($entryname = readdir($current_dir))
	{
		if(is_dir("$dir/$entryname") and ($entryname != "." and $entryname!=".."))
		{
			deldir("${dir}/${entryname}");
		}
		elseif($entryname != "." and $entryname!="..")
		{
			unlink("${dir}/${entryname}");
		}
	}
	closedir($current_dir);
	rmdir($dir);
}

?>
