<?php

	require_once(dirname(__FILE__).'/class.adminview.php');

	class AKB_TOOLS extends AdminView
	{
		var $tables = array (
			'categories',
			'categoryassociations',
			'comments',
			'glossary',
			'groups',
			'members',
			'questions',
			'questions_history',
			'question_auth',
			'questions_customfields',
			'ratings',
			'searchhistory',
			'submittedquestions',
			'subscribers',
			'users',
			'userlogin',
			'customfields',
			'customfields_data',
			'pageindex',
			'newss'
		);

		var $backupfiles = array();

		/**
		* HandlePage
		*
		* Handles page routing based on the current ToDo get string
		* @return void
		*/
		function HandlePage()
		{
			if (isset($_GET['ToDo'])) {
				switch (strtolower($_GET['ToDo'])) {
					case 'dodbbackup':
						if ($_SESSION['user']->verify('backup', 'create')) {
							$this->BackupDatabase();
						} else {
							$this->NoPermission();
						}
					break;
					case 'doindexattachment':
						if ($_SESSION['user']->verify('setting', 'edit')) {
							$this->IndexAttachments();
						} else {
							$this->NoPermission();
						}
					break;
					case 'dobackupdatabase':
						if ($_SESSION['user']->verify('backup', 'create')) {
							$this->BackupDatabase();
						} else {
							$this->NoPermission();
						}
					break;
					case 'indexattachmentsinit':
						if ($_SESSION['user']->verify('setting', 'edit')) {
							$this->IndexAttachmentsInit();
						} else {
							$this->NoPermission();
						}
					break;
					case 'backupdatabaseinit':
						if ($_SESSION['user']->verify('backup', 'create')) {
							$this->BackupDatabaseInit();
						} else {
							$this->NoPermission();
						}
					break;
					case 'backupdatabase':
						if ($_SESSION['user']->verify('backup', 'create')) {
							$this->ShowBackupDatabase();
						} else {
							$this->NoPermission();
						}
					break;
					case 'indexattachments':
						if ($_SESSION['user']->verify('setting', 'edit')) {
							$this->ShowIndexAttachments();
						} else {
							$this->NoPermission();
						}
					break;
					case 'backupdone':
						if ($_SESSION['user']->verify('backup', 'create')) {
							$GLOBALS['Message'] = MessageBox(sprintf(GetLang('BackupSuccessful'), htmlspecialchars($_GET['file'], ENT_QUOTES, $GLOBALS['charset'])), MSG_SUCCESS);
							$this->ShowManageBackups();
						} else {
							$this->NoPermission();
						}
					break;
					case 'indexdone':
						if ($_SESSION['user']->verify('setting', 'edit')) {
							$GLOBALS['Message'] = MessageBox(GetLang('IndexSuccessful'), MSG_SUCCESS);
							$this->ShowIndexAttachments();
						} else {
							$this->NoPermission();
						}
					break;
					case 'backupconfig':
						if ($_SESSION['user']->verify('backup', 'create')) {
							$this->BackupConfig();
							$this->ShowManageBackups();
						} else {
							$this->NoPermission();
						}
					break;
					case 'managebackups':
					default:
						if ($_SESSION['user']->verify('backup', 'create')
						|| $_SESSION['user']->verify('backup', 'delete')) {
							if (isset($_POST['bulkaction'])) {
								$this->BulkAction();
							} else {
								$this->ShowManageBackups();
							}
						} else {
							$this->NoPermission();
						}
				}
			}
		}

		/**
		* BulkAction
		*
		* Performs an action on multiple items at once
		*
		* @return bool false if a required post var wasnt set
		*/
		function BulkAction()
		{
			if (!isset($_POST['bulkaction'])) {
				$this->ShowManageBackups();
				return false;
			}

			if (!isset($_POST['item']) || !is_array($_POST['item'])) {
				$this->ShowManageBackups();
				return false;
			}

			if (empty($_POST['item'])) {
				$this->ShowManageBackups();
				return false;
			}
			switch (strtolower($_POST['bulkaction'])) {
				case 'delete':
					if ($_SESSION['user']->verify('backup', 'delete')) {
						$pass = true;
						foreach ($_POST['item'] as $filename => $on) {
							$_GET['filename'] = $filename;
							if (!$this->DeleteBackup()) {
								$pass = false;
							}
						}
						if ($pass) {
							$GLOBALS['Message'] .= MessageBox(GetLang('FileDeleteOk'), MSG_SUCCESS);
						} else {
							$GLOBALS['Message'] .= MessageBox(GetLang('FileDeleteProblem'), MSG_ERROR);
						}
					} else {
						$this->ShowManageBackups();
						return false;
					}
				break;
			}
			$this->ShowManageBackups();

		}

		/**
		* GetCreateTable
		*
		* Returns the create table definition for a table
		* @return string Returns the create table definition for a table
		*/
		function GetCreateTable($table)
		{
			$query = "SHOW CREATE TABLE $table";
			$result = mysql_query($query) or trigger_error('Error: '.mysql_error(), E_USER_ERROR);
			$row = mysql_fetch_assoc($result);
			return $row['Create Table'].";\n";
		}

		/**
		* GetData
		*
		* Returns all the insert into commands to populate a table
		* @return string Returns all the insert into commands to populate a table
		*/
		function GetData($table)
		{
			$output = '';
			$query = "SELECT * FROM $table";
			$result = mysql_unbuffered_query($query) or trigger_error('Error: '.mysql_error(), E_USER_ERROR);
			$fields = getFields($table);
			while ($row = mysql_fetch_assoc($result)) {
				$line = "INSERT INTO $table (`";
				$line .= implode("`, `", $fields);
				$line .= "`) VALUES ('";
				$line .= implode("', '", array_map('mysql_escape_string', $row));
				$line .= "')";
				$output .= "$line;\n";
			}
			return $output;
		}

		/**
		* GetFields
		*
		* Return all the field names of the table as an array
		* @return string Return all the field names of the table as an array
		*/
		function GetFields($table)
		{
			$query = "SHOW COLUMNS FROM $table";
			$result = mysql_query($query) or trigger_error('Error: '.mysql_error(), E_USER_ERROR);
			$fields = array();
			while ($row = mysql_fetch_assoc($result)) {
				$fields[] = $row['Field'];
			}
			return $fields;
		}

		/**
		* ShowManageBackups
		*
		* Show the screen for managing backups
		* @return void
		*/
		function ShowManageBackups()
		{
			if (!$_SESSION['user']->verify('backup', 'create')
			&& !$_SESSION['user']->verify('backup', 'delete')) {
				$this->NoPermission();
				return;
			}
			
			$GLOBALS['BreadcrumEntries'][GetLang("ManageBackups")] = "";			

			$t = $GLOBALS['AKB_CLASS_TEMPLATE'];
			$GLOBALS['Grid'] = '';
			$GLOBALS['FormAction'] = $GLOBALS['pathToKB'].'/admin/index.php?ToDo=manageBackups';

			if ($_SESSION['user']->verify('backup', 'create')) {
				$GLOBALS['ShowBackupCreate'] = 'inline';
			} else {
				$GLOBALS['ShowBackupCreate'] = 'none';
			}
			if ($_SESSION['user']->verify('backup', 'delete')) {
				$GLOBALS['ShowBackupDelete'] = 'inline';
			} else {
				$GLOBALS['ShowBackupDelete'] = 'none';
			}

			if (isset($_REQUEST['complete']) && $_REQUEST['complete'] == 1) {
				$GLOBALS['Message'] = MessageBox(GetLang('BackupDatabaseSuccessful'),MSG_SUCCESS);
			}
			
			$this->GetBackupFileList();
			if (!empty($this->backupfiles)) {
				$t->SetTemplate('backup.row');
				foreach ($this->backupfiles as $filename => $details) {
					$GLOBALS['Filename'] = htmlspecialchars($filename, ENT_QUOTES, $GLOBALS['charset']);
					$GLOBALS['Size'] = $this->NiceSize($details['size']);
					$GLOBALS['ModifiedTime'] = $this->NiceTime($details['mtime']);

					$GLOBALS['Text'] = GetLang('Download');
					$data = base64_encode('backup|'.$filename);
					$GLOBALS['Href'] = $GLOBALS['pathToKB'].'/admin/index.php?ToDo=download&amp;data='.$data;
					$GLOBALS['DownloadLink'] = $GLOBALS['AKB_CLASS_TEMPLATE']->GetSnippet('LinkCurrentWindow');

					$GLOBALS['Grid'] .= $t->ParseTemplate(true);
					
					if (strncasecmp($GLOBALS['Filename'], 'settings', strlen('settings'))) {
						$latestBackupLink = $GLOBALS['Href'];
						$latestBackupFilename = $GLOBALS['Filename'];
					}
					
				}
				
				if (isset($_REQUEST['complete']) && $_REQUEST['complete'] == 1 && isset($latestBackupFilename)) {
					$GLOBALS['Href'] = $latestBackupLink;
					$GLOBALS['Text'] = $latestBackupFilename;
					$GLOBALS['Message'] = MessageBox(sprintf(GetLang('BackupSuccessful'), $GLOBALS['AKB_CLASS_TEMPLATE']->GetSnippet('LinkCurrentWindow')),MSG_SUCCESS);
				}
				
				$t->SetTemplate('backup.manage');
				$t->ParseTemplate();
			} else {
				$GLOBALS['Message'] = MessageBox(GetLang('BackupNoFilesMessage'), MSG_SUCCESS);
				$t->SetTemplate('backup.empty');
				$t->ParseTemplate();
			}
		}

		/**
		* GetBackupFileList
		*
		* Gets a list of backup files and sets the backupfilelist member var
		*
		* @return void
		*/
		function GetBackupFileList()
		{
			if (!defined('BACKUP_DIR')) {
				trigger_error("Expected BACKUP_DIR to be defined, but it wasn't", E_USER_ERROR);
			}

			// Make sure the directory exists
			if (!is_dir(BACKUP_DIR)) {
				if (@mkdir(BACKUP_DIR, 0777)) {
					chmod(BACKUP_DIR, 0777);
				}
			}
			if (is_dir(BACKUP_DIR)) {
				$d = opendir(BACKUP_DIR);
				if ($d) {
					while (($entry = readdir($d)) !== false) {
						if ($entry != '.'
						&& $entry != '..'
						&& $entry != 'CVS') {
							$filepath = BACKUP_DIR.DS.$entry;
							if (!is_file($filepath)) {
								continue;
							}
							$this->backupfiles[$entry]['size'] = filesize($filepath);
							$this->backupfiles[$entry]['mtime'] = filemtime($filepath);
						}
					}
					closedir($d);
				}
			}
		}

		/**
		* NiceSize
		*
		* Returns a datasize formatted into the most relevant units
		* @return string The formatted filesize
		* @param int Size In Bytes
		*/
		function NiceSize($SizeInBytes=0)
		{
			if ($SizeInBytes > 1024 * 1024 * 1024) {
				$suffix = 'GB';
				return sprintf("%01.2f %s", $SizeInBytes / (1024 * 1024 * 1024), $suffix);
			} elseif ($SizeInBytes > 1024 * 1024 ) {
				$suffix = 'MB';
				return sprintf("%01.2f %s", $SizeInBytes / (1024 * 1024), $suffix);
			} elseif ($SizeInBytes > 1024) {
				$suffix = 'KB';
				return sprintf("%01.2f %s", $SizeInBytes / 1024, $suffix);
			} elseif ($SizeInBytes < 1024) {
				$suffix = 'B';
				return sprintf("%d %s", $SizeInBytes, $suffix);
			}
		}

		/**
		* NiceTime
		*
		* Returns a formatted timestamp
		* @return string The formatted string
		* @param int The unix timestamp to format
		*/
		function NiceTime($UnixTimestamp)
		{
			return date('jS F Y H:i:s', $UnixTimestamp);
		}

		/**
		* DeleteBackup
		*
		* Basically deletes a file - but it checks to make sure the file is
		* in the backup directory before deleting
		*
		* @return boolen Returns true if successful
		*/
		function DeleteBackup()
		{
			if (!$_SESSION['user']->verify('backup', 'delete')) {
				$this->NoPermission();
				return false;
			}

			if (!defined('BACKUP_DIR')) {
				trigger_error("Expected BACKUP_DIR to be defined, but it wasn't", E_USER_ERROR);
			}

			if (!isset($_GET['filename']) || empty($_GET['filename'])) {
				$GLOBALS['Message'] = MessageBox(GetLang('DeleteFilenameEmpty'), MSG_ERROR);
				return false;
			}

			$filename = $_GET['filename'];

			$easypath = BACKUP_DIR.DIRECTORY_SEPARATOR.$filename;
			$realpath = realpath(BACKUP_DIR.DIRECTORY_SEPARATOR.$filename);

			// Somethings not as we are expecting and its a bad idea to continue
			// in case the cause of things going wrong are security related
			if ($easypath != $realpath) {
				$GLOBALS['Message'] = MessageBox(GetLang('DeleteFilePathError'), MSG_ERROR);
				return false;
			}

			if (!file_exists($realpath)) {
				$GLOBALS['Message'] = MessageBox(GetLang('DeleteFileNotFound'), MSG_ERROR);
				return false;
			}

			return unlink($realpath);
		}

		/**
		* BackupConfig
		*
		* Copies the config to a timestamped filename in the backups directory
		* @return boolen Return true if backup succeeds
		*/
		function BackupConfig()
		{
			if (!$_SESSION['user']->verify('backup', 'create')) {
				$this->NoPermission();
				return false;
			}

			if (!defined('BACKUP_DIR')) {
				trigger_error("Expected BACKUP_DIR to be defined, but it wasn't", E_USER_ERROR);
			}

			if (!is_dir(BACKUP_DIR)) {
				$GLOBALS['Message'] = MessageBox(GetLang('BackupDirectoryNotFound'), MSG_ERROR);
				return false;
			}

			$srcfile = dirname(__FILE__).'/../config.php';
			$outfile = 'settings-'.date('Y-m-d-H-i-s').'_'. md5(sha1(mt_rand().mt_rand()).microtime()) . '.php';
			$destfile = BACKUP_DIR.DIRECTORY_SEPARATOR.$outfile;

			if (!file_exists($srcfile)) {
				$GLOBALS['Message'] = MessageBox(GetLang('ConfigNotFound'), MSG_ERROR);
				return false;
			}

			if (file_exists($destfile)) {
				$GLOBALS['Message'] = MessageBox(sprintf(GetLang('BackupFileExists'), $destfile), MSG_ERROR);
				return false;
			}

			if (copy($srcfile, $destfile)) {
				$data = base64_encode('backup|'.$outfile);
				$GLOBALS['Href'] = $GLOBALS['pathToKB'].'/admin/index.php?ToDo=download&amp;data='.$data;
				$GLOBALS['Text'] = $outfile;
				$GLOBALS['Message'] = MessageBox(sprintf(GetLang('ConfigFileBackupOk'), $GLOBALS['AKB_CLASS_TEMPLATE']->GetSnippet('LinkCurrentWindow')),MSG_SUCCESS);
			} else {
				$GLOBALS['Message'] = MessageBox(GetLang('ConfigFileBackupProblem'), MSG_ERROR);
			}
		}

		/**
		* ShowBackupDatabase
		*
		* Shows the backup the database screen to the user.
		*
		* @return void
		*/
		function ShowBackupDatabase()
		{
			if (!$_SESSION['user']->verify('backup', 'create')) {
				$this->NoPermission();
				return;
			}

			if (function_exists('gzencode')) {
				$GLOBALS['ShowBackupButton'] = 'block';
			} else {
				$GLOBALS['ShowBackupButton'] = 'none';
				$GLOBALS['Message'] = MessageBox(GetLang('GzencodeRequired'), MSG_ERROR);
			}

			$GLOBALS['NumTables'] = count($this->tables);
			$GLOBALS['NumRows'] = 0;

			$first = true;

			foreach ($this->tables as $table) {

				$query = "SELECT COUNT(*) FROM ".$GLOBALS['tablePrefix'].$table;
				$rows = $GLOBALS['AKB_DB']->FetchOne($query);

				if ($first) {
					$GLOBALS['MinRows'] = $rows;
					$GLOBALS['MaxRows'] = $rows;
					$GLOBALS['MinRowTableName'] = $GLOBALS['tablePrefix'].$table;
					$GLOBALS['MaxRowTableName'] = $GLOBALS['tablePrefix'].$table;
					$first = false;
				}

				$GLOBALS['NumRows'] += $rows;

				if ($rows > $GLOBALS['MaxRows']) {
					$GLOBALS['MaxRows'] = $rows;
					$GLOBALS['MaxRowTableName'] = $GLOBALS['tablePrefix'].$table;
				}
				if ($rows < $GLOBALS['MinRows']) {
					$GLOBALS['MinRows'] = $rows;
					$GLOBALS['MinRowTableName'] = $GLOBALS['tablePrefix'].$table;
				}
			}

			$GLOBALS['MaxRows'] = number_format($GLOBALS['MaxRows']);
			$GLOBALS['MinRows'] = number_format($GLOBALS['MinRows']);
			$GLOBALS['NumRows'] = number_format($GLOBALS['NumRows']);

			$t = $GLOBALS['AKB_CLASS_TEMPLATE'];
			$t->SetTemplate('backup.database');
			$t->ParseTemplate();
		}


		/**
		* ShowIndexAttachments
		*
		* Shows the attachments indexing screen to the user.
		*
		* @return void
		*/
		function ShowIndexAttachments()
		{
			if (!$_SESSION['user']->verify('setting', 'edit')) {
				$this->NoPermission();
				return;
			}
			
			if (!$GLOBALS['enableAttachmentSearch']) {
				return;
			}
			
			$GLOBALS['BreadcrumEntries'][GetLang("IndexAttachments")] = "";
			// Get the ids of all the articles.
			$attachments = array();
			$query = "SELECT questionid FROM ".$GLOBALS['tablePrefix']."questions";
			$result = $GLOBALS['AKB_DB']->Query($query);
			$GLOBALS['totalFiles'] = 0;
			$GLOBALS['totalExtension'] = '';
			$validExtension = $GLOBALS['AKB_CLASS_FILEINDEX']->getValidExtension();
			$displayExtensionList = array();
			
			while ($row = $GLOBALS['AKB_DB']->Fetch($result)) {
				$questionid = $row['questionid'];
				$attachmentsFolder = ATTACHMENT_DIR . DS . $questionid;
				if (file_exists($attachmentsFolder) && is_dir($attachmentsFolder)) {
					if ($handle = opendir($attachmentsFolder)) {
					    while (false !== ($attachment = readdir($handle))) {
					    	if ($attachment != "." && $attachment != "..") {
					        	$extension = array_pop(explode(".", $attachment));
					    		if (isset($validExtension[$extension])) {
					    			if (!isset($displayExtensionList[$extension])) {
					    				$displayExtensionList[$extension] = 0;
					    			}
					    			$displayExtensionList[$extension]++;
					    			$GLOBALS['totalFiles']++;
					    		}
					    	}
					    }
					    closedir($handle);
					}
				}
			}
			if ($GLOBALS['totalFiles'] <= 0) {
				$GLOBALS['ShowBackupButton'] = 'none;';
				$GLOBALS['Message'] = MessageBox(GetLang('NoAttachmentMessage'), MSG_SUCCESS);
			} else if ($GLOBALS['totalFiles'] == 1) {
				$GLOBALS['AttachmentIndexingIntroMessage'] = sprintf(GetLang('TotalIndexFilesSingularMessage'),$GLOBALS['totalFiles']);
			} else {
				$GLOBALS['AttachmentIndexingIntroMessage'] = sprintf(GetLang('TotalIndexFilesPluralMessage'),$GLOBALS['totalFiles']);
			}
			
			
			if (sizeof($displayExtensionList)) {
				while (list($k, $v) = each($displayExtensionList)) {
					$GLOBALS['totalExtension'] .= '<li>Total number of .'.$k.' files to be indexed: '.$v.'</li>';
				}
			}
			if (isset($_REQUEST['complete']) && $_REQUEST['complete'] == 1) {
				if ($GLOBALS['totalFiles'] == 1) {
					$GLOBALS['Message'] = MessageBox(sprintf(GetLang('IndexSuccessfulSingular'), $GLOBALS['totalFiles']),MSG_SUCCESS);
				} else if ($GLOBALS['totalFiles'] > 1) {
					$GLOBALS['Message'] = MessageBox(sprintf(GetLang('IndexSuccessfulPlural'), $GLOBALS['totalFiles']),MSG_SUCCESS);
				}
				$GLOBALS['totalExtension'] = '';
				$GLOBALS['totalFiles'] = '';
				$GLOBALS['ShowBackupButton'] = 'none';
			}
			
			$t = $GLOBALS['AKB_CLASS_TEMPLATE'];
			$t->SetTemplate('attachmentindexing.show');
			$t->ParseTemplate();
		}

		// {{{ BackupDatabase
		/**
		* BackupDatabase
		*
		* Backups up a datbase to a file.
		* @return boolean Returns true on success, false on a problem
		*/
		function BackupDatabase()
		{
			if (!$_SESSION['user']->verify('backup', 'create')) {
				
				$this->NoPermission();
				return false;
			}
			
			if (!defined('BACKUP_DIR')) {
				trigger_error("Expected BACKUP_DIR to be defined, but it wasn't", E_USER_ERROR);
			}

			if (!ini_get('safe_mode')) {
				set_time_limit(0);
			}

			// wheres my outfile going to go ?
			$rand = md5(sha1(mt_rand().mt_rand()).microtime());
			$filename = 'backup-'.date('Y-m-d-H-i-s').'_'. $rand .'.sql.gz';
			$tmpfile  = 'backup-'.date('Y-m-d-H-i-s').'_'. $rand .'.sql.gz.incomplete';
			$outdir = BACKUP_DIR.DIRECTORY_SEPARATOR;
			ini_set("zlib.output_compression", "Off");
			session_write_close();

			$start_time = microtime_float();
			$output = '';

			// Disable all output buffering - we want our headers to make it
			// to the clients browsers
			while (ob_get_level()) {
				ob_end_clean();
			}
			
			if (file_exists($outdir.$tmpfile)) {
				$GLOBALS['Message'] = MessageBox(sprintf(GetLang('BackupFileExists'), $tmpfile), MSG_ERROR);
				return false;
			}

			if (file_exists($outdir.$filename)) {
				$GLOBALS['Message'] = MessageBox(sprintf(GetLang('BackupFileExists'), $filename), MSG_ERROR);
				return false;
			}

			// init the database backup title & intro
			$GLOBALS['ProgressTitle'] = GetLang('BackupDatabaseInProgress');
			$GLOBALS['ProgressIntro'] = GetLang('BackupDatabaseInProgressIntro');
			
			$t = $GLOBALS['AKB_CLASS_TEMPLATE'];
			$t->SetTemplate("pageheader.popup");
			$t->ParseTemplate();
			$t->SetTemplate('progress.status');
			$t->ParseTemplate();

			$this->_UpdateProgress(GetLang('BackupDatabaseStatusStart'), 0);
			$tableBackedupCount = 0;
			if (isset($GLOBALS['databaseType']) && $GLOBALS['databaseType'] == 'mssql') {
				$installationSchema = AKB_ROOT.DS.'admin'.DS.'templates'.DS.'install.schema.'.$GLOBALS['databaseType'].'.tpl';
				if (!file_exists($installationSchema)) {
					$GLOBALS['Message'] = MessageBox(sprintf(GetLang('InstallationSchemaNotExist'), $installationSchema), MSG_ERROR);
					return false;
				}
				// Copy from the existing Installation Schema.
				$fp  = fopen($outdir.$tmpfile, "a+b");
				$output = file_get_contents($installationSchema);
				$output = str_replace('%%GLOBAL_tablePrefix%%', $GLOBALS['tablePrefix'], $output);
				$output = str_replace('__SEMI_COLUMN__', ' ; ', $output); // to get rid of the semi column alias
				$output.="\n\n";
				$totalTables = sizeof($this->tables);
				foreach ($this->tables as $table) {
					$tableBackedupCount++;
					$percentage = ceil(($tableBackedupCount/$totalTables)*100);
					$message = sprintf(GetLang('BackupDatabaseStatusDesc'),number_format($tableBackedupCount, 0),number_format(sizeof($totalTables), 0));
					$this->_UpdateProgress($message, $percentage);
					
					$query = "SELECT * FROM INFORMATION_SCHEMA.Columns where TABLE_NAME = '".$GLOBALS['tablePrefix']."$table' ORDER BY ORDINAL_POSITION";
					$fields = array();
					$result = $GLOBALS['AKB_DB']->Query($query);
					while ($row = $GLOBALS['AKB_DB']->Fetch($result)) {
						$fields[] = $row['COLUMN_NAME'];
					}
					$query = "SELECT * FROM ".$GLOBALS['tablePrefix']."$table ";
					$result = $GLOBALS['AKB_DB']->Query($query);
					$output .= "IF OBJECTPROPERTY ( object_id('".$GLOBALS['tablePrefix']."$table'),'TableHasIdentity') = 1 BEGIN SET IDENTITY_INSERT ".$GLOBALS['tablePrefix']."$table ON END";
					$output .= ";\n";
					
					while ($row = $GLOBALS['AKB_DB']->Fetch($result)) {
						$line  = "INSERT INTO ".$GLOBALS['tablePrefix'].$table." (";
						$line .= implode(", ", $fields);
						$line .= ") VALUES ('";
						$line .= implode("', '", array_map(array($GLOBALS['AKB_DB'], 'Quote'), array_values($row)));
						$line .= "')";
						$line .= ";\n";
						$output .= $line;
						if (strlen($output) > EXPORT_CHUNKSIZE) {
							$encoded = gzencode($output);
							if ($fp) {
								fwrite($fp, $encoded, strlen($encoded));
							}
							$encoded = '';
							$output = '';
							if (microtime_float() > $start_time + 30) {
								header('X-ping: pong');
							}
						}
					}
					$output .= "IF OBJECTPROPERTY ( object_id('".$GLOBALS['tablePrefix']."$table'),'TableHasIdentity') = 1 BEGIN SET IDENTITY_INSERT ".$GLOBALS['tablePrefix']."$table OFF END";
					$output .= ";\n";

					$encoded = gzencode($output);
					if ($fp) {
						fwrite($fp, $encoded, strlen($encoded));
					}
					$encoded = '';
					$output = '';
					if (microtime_float() > $start_time + 30) {
						header('X-ping: pong');
					}
					
				}
			} elseif (isset($GLOBALS['databaseType']) && $GLOBALS['databaseType'] == 'oci8') {
				$installationSchema = AKB_ROOT.DS.'admin'.DS.'templates'.DS.'install.schema.'.$GLOBALS['databaseType'].'.tpl';
				if (!file_exists($installationSchema)) {
					$GLOBALS['Message'] = MessageBox(sprintf(GetLang('InstallationSchemaNotExist'), $installationSchema), MSG_ERROR);
					return false;
				}
				// Copy from the existing Installation Schema.
				$fp  = fopen($outdir.$tmpfile, "a+b");
				$output = file_get_contents($installationSchema);
				$output = str_replace('%%GLOBAL_tablePrefix%%', $GLOBALS['tablePrefix'], $output);
				$output = str_replace(';', ' GO ', $output); // to get rid of the semi column alias
				$output = str_replace('__SEMI_COLUMN__', ' ; ', $output); // to get rid of the semi column alias
				$output.="\n\n";
				$totalTables = sizeof($this->tables);
				$output .= "\n\nALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS'\nGO\n\n";
				foreach ($this->tables as $table) {
					$tableBackedupCount++;
					$percentage = ceil(($tableBackedupCount/$totalTables)*100);
					$message = sprintf(GetLang('BackupDatabaseStatusDesc'),number_format($tableBackedupCount, 0),number_format(sizeof($totalTables), 0));
					$this->_UpdateProgress($message, $percentage);
					$query = "SELECT * FROM ".$GLOBALS['tablePrefix']."$table ";
					$result = $GLOBALS['AKB_DB']->Query($query);
					while ($row = $GLOBALS['AKB_DB']->Fetch($result)) {
						$line  = "INSERT INTO ".$GLOBALS['tablePrefix'].$table." ";
						$line .= " VALUES ('";
						$line .= implode("', '", array_map(array($GLOBALS['AKB_DB'], 'Quote'), array_values($row)));
						$line .= "')";
						$line .= "\nGO\n\n";
						$output .= $line;
						if (strlen($output) > EXPORT_CHUNKSIZE) {
							$encoded = gzencode($output);
							if ($fp) {
								fwrite($fp, $encoded, strlen($encoded));
							}
							$encoded = '';
							$output = '';
							if (microtime_float() > $start_time + 30) {
								header('X-ping: pong');
							}
						}
					}
					$encoded = gzencode($output);
					if ($fp) {
						fwrite($fp, $encoded, strlen($encoded));
					}
					$encoded = '';
					$output = '';
					if (microtime_float() > $start_time + 30) {
						header('X-ping: pong');
					}
				}
			} else {
				$fp = fopen($outdir.$tmpfile, "a+b");
				$totalTables = sizeof($this->tables);
				foreach ($this->tables as $table) {
					$tableBackedupCount++;
					$percentage = ceil(($tableBackedupCount/$totalTables)*100);
					$message = sprintf(GetLang('BackupDatabaseStatusDesc'),number_format($tableBackedupCount, 0),number_format(sizeof($totalTables), 0));
					$this->_UpdateProgress($message, $percentage);
					
					$output.= $this->GetCreateTable($GLOBALS['tablePrefix'].$table);
					// Fetch 1 row of data so we can get the field names
					$query = "SELECT * FROM ".$GLOBALS['tablePrefix']."$table LIMIT 1";
					$result = mysql_query($query) or trigger_error('Error: '.mysql_error(), E_USER_ERROR);
					$fields = $this->GetFields($GLOBALS['tablePrefix'].$table);
	
					// Fetch all the data
					$query = "SELECT * FROM ".$GLOBALS['tablePrefix']."$table ";
					$result = mysql_unbuffered_query($query) or trigger_error('Error: '.mysql_error(), E_USER_ERROR);
					while ($row = mysql_fetch_assoc($result)) {
						$line  = "INSERT INTO ".$GLOBALS['tablePrefix'].$table." (`";
						$line .= implode("`, `", $fields);
						$line .= "`) VALUES ('";
						$line .= implode("', '", array_map('mysql_real_escape_string', $row));
						$line .= "')";
						$line .= ";\n";
						$output .= $line;
						if (strlen($output) > EXPORT_CHUNKSIZE) {
							$encoded = gzencode($output);
							if ($fp) {
								fwrite($fp, $encoded, strlen($encoded));
							}
							$encoded = '';
							$output = '';
							if (microtime_float() > $start_time + 30) {
								header('X-ping: pong');
							}
						}
					}
					$encoded = gzencode($output);
					if ($fp) {
						fwrite($fp, $encoded, strlen($encoded));
					}
					$encoded = '';
					$output = '';
					if (microtime_float() > $start_time + 30) {
						header('X-ping: pong');
					}
				}
			}
			if ($fp) {
				fclose($fp);
				rename($outdir.$tmpfile, $outdir.$filename);
			}
			$this->_UpdateProgress(GetLang('BackupDatabaseStatusComplete'), 100);
			echo "<script type='text/javascript'>\n";
			echo "self.parent.location = 'index.php?ToDo=manageBackups&complete=1';\n";
			echo "</script>";
		}
		
		/**
		* BackupDatabaseInit
		*
		* Initialize the loading page and do the attachments index
		*
		* @return void
		*/
		function BackupDatabaseInit()
		{
			$redirectURL = '';
			foreach($_GET as $k => $v) {
				if($k == "ToDo") {
					continue;
				}
				$redirectURL .= sprintf("&%s=%s", urlencode($k), urlencode($v));
			}
			echo sprintf('<script type="text/javascript">window.onload = function() { window.location = "index.php?ToDo=doBackupDatabase%s"; }</script>', $redirectURL, $redirectURL);
			exit;
		}
		
		/**
		* IndexAttachmentsInit
		*
		* Initialize the loading page and do the attachments index
		*
		* @return void
		*/
		function IndexAttachmentsInit()
		{
			$redirectURL = '';
			foreach($_GET as $k => $v) {
				if($k == "ToDo") {
					continue;
				}
				$redirectURL .= sprintf("&%s=%s", urlencode($k), urlencode($v));
			}
			echo sprintf('<script type="text/javascript">window.onload = function() { window.location = "index.php?ToDo=doIndexAttachment%s"; }</script>', $redirectURL, $redirectURL);
			exit;
		}
		
		function _UpdateProgress($message = '', $percentage = 0)
		{
			echo sprintf("<script type=\"text/javascript\">updateProgress('%s', '%s');</script>\n", $percentage, $message);
			@ob_flush();
			@flush();
		}
		
		// }}}
		// {{{ IndexAttachments
		/**
		* IndexAttachments
		*
		* Index Attachment content to database.
		* @return boolean Returns true on success, false on a problem
		*/
		function IndexAttachments()
		{
			if (!$_SESSION['user']->verify('setting', 'edit')) {
				$this->NoPermission();
				return false;
			}
			
			if (!$GLOBALS['enableAttachmentSearch']) {
				return false;
			}
			
			if (!defined('ATTACHMENT_DIR')) {
				trigger_error("Expected ATTACHMENT_DIR to be defined, but it wasn't", E_USER_ERROR);
			}

			if (!ini_get('safe_mode')) {
				set_time_limit(0);
			}
			
			// init the attachments indexing title & intro
			$GLOBALS['ProgressTitle'] = GetLang('IndexAttachmentsInProgress');
			$GLOBALS['ProgressIntro'] = GetLang('IndexAttachmentsIntro');
			
			$t = $GLOBALS['AKB_CLASS_TEMPLATE'];
			$t->SetTemplate("pageheader.popup");
			$t->ParseTemplate();
			$t->SetTemplate('progress.status');
			$t->ParseTemplate();

			flush();
			ob_flush();
			
			$this->_UpdateProgress(GetLang('IndexAttachmentsStatusStart'), 0);
			
			// Preparing data to be inserted to page index table
			$query = "SELECT questionid FROM ".$GLOBALS['tablePrefix']."questions";
			$result = $GLOBALS['AKB_DB']->Query($query);
			$GLOBALS['message'] = MessageBox(sprintf(GetLang('IndexSuccessful'), MSG_SUCCESS));
			$GLOBALS['totalFiles'] = 0;
			$GLOBALS['totalExtension'] = '';
			$validExtension = $GLOBALS['AKB_CLASS_FILEINDEX']->getValidExtension();
			$displayExtensionList = array();
			$insertQuery = array();
			
			while ($row = $GLOBALS['AKB_DB']->Fetch($result)) {
				$questionid = $row['questionid'];
				$attachmentsFolder = ATTACHMENT_DIR . DS . $questionid;
				$attachmentsUrl = $GLOBALS['pathToKB'] . '/attachments/' . $questionid;
				if (file_exists($attachmentsFolder) && is_dir($attachmentsFolder)) {
					if ($handle = opendir($attachmentsFolder)) {
					    while (false !== ($attachment = readdir($handle))) {
					    	if ($attachment != "." && $attachment != "..") {
    							$attachmentFullPath = $attachmentsUrl.'/'.html_entity_decode($attachment);
					        	$extension = array_pop(explode(".", $attachment));
					    		if (isset($validExtension[$extension])) {
					    			if (!isset($displayExtensionList[$extension])) {
					    				$displayExtensionList[$extension] = 0;
					    			}
					    			// Create instance of needed plugin.
					    			$pluginName = $GLOBALS['AKB_CLASS_FILEINDEX']->getPlugin($extension);
					    			
					    			if ($pluginName) {
						    			$lastupdated = date("Y-m-d H:i:s");
						    			$newData = array(
						    			'fullurl' => ' ', 
						    			'questionid' => $questionid, 
						    			'content' => ' ', 
						    			'plugin' => ' ', 
						    			'filename' => $attachment, 
						    			'lastupdated' => $lastupdated
						    			);
						    			
						    			$insertQuery[] = array('query' => $newData, 'plugin' => $pluginName, 'path' => $attachmentFullPath, 'url' => $attachmentsFolder);
					    			}
					    		}
					    	}
					    }
					    closedir($handle);
					}
				}
			}
			$insertCount = 0;
			$query = "TRUNCATE TABLE ".$GLOBALS['tablePrefix']."pageindex";
			$GLOBALS['AKB_DB']->Query($query);
			if (is_array($insertQuery) && sizeof($insertQuery)) {
				foreach ($insertQuery as $eachQuery) {
					$insertCount++;
					
	    			$plugin = new $eachQuery['plugin']();
	    			$rawContent = getPage(str_replace(' ', '%20', $eachQuery['path']));
	    			$attachmentContent = @$plugin->Parse($rawContent, $eachQuery['url']);
	    			$attachmentContent = $GLOBALS['AKB_DB']->quote($attachmentContent);
	    			$attachmentContentCopy = '';
					if ($eachQuery['plugin'] == 'External_Ppt_Plugin' || $eachQuery['plugin'] == 'Pdf_Plugin') {
						$attachmentContentCopy = stripPluginHeader($attachmentContent);
					} else if ($eachQuery['plugin'] == 'External_Doc_Plugin') {
						$attachmentContentCopy = str_replace('\r\n', ' ', $attachmentContent);
					}
					if ($attachmentContentCopy != '') {
						$attachmentContent = $attachmentContentCopy;
					}
//					$eachQuery['query'] = sprintf($eachQuery['query'], $eachQuery['path'], $attachmentContent, $eachQuery['plugin']);

					
					$eachQuery['query']['fullurl'] = $eachQuery['path'];
					$eachQuery['query']['content'] = $attachmentContent;
					$eachQuery['query']['plugin'] = $eachQuery['plugin'];
					$GLOBALS['AKB_DB']->InsertQuery($GLOBALS['tablePrefix'].'pageindex', $eachQuery['query']);
					
					if ($insertCount % 100 == 0) {
						$percentage = ceil(($insertCount/(sizeof($insertQuery)))*100);
						$message = sprintf(GetLang('IndexAttachmentsStatusDesc'),number_format($insertCount, 0),number_format(sizeof($insertQuery), 0));
						$this->_UpdateProgress($message, $percentage);
					}
				}
			}
			if (isset($GLOBALS['enableFullindexPopulation']) && $GLOBALS['enableFullindexPopulation'] == true) {
				$GLOBALS['AKB_DB']->UpdateFullTextIndex (array($GLOBALS['tablePrefix'].'pageindex'), array($GLOBALS['tablePrefix'].'PI_FI_T', $GLOBALS['tablePrefix'].'PI_FI_A'));
			}
			$this->_UpdateProgress(GetLang('IndexAttachmentsStatusComplete'), 100);
			echo "<script type='text/javascript'>\n";
			echo "self.parent.location = 'index.php?ToDo=indexAttachments&complete=1';\n";
			echo "</script>";
		}
		// }}}
	}

?>
