<?php
// +----------------------------------------------------------------+
// | step2.php														|
// |																|
// | Function: Collect DB Server info and create Atmail database	|
// +----------------------------------------------------------------+
// | Source-code (C) CalaCode.com 1998-2009 . All rights reserved	|
// | See http://calacode.com/license.ehtml for license agreement	|
// +----------------------------------------------------------------+
// | Date: May 2009													|
// +----------------------------------------------------------------+


// Make sure we are included from install/index.php, exit if not
if (!defined('ATMAIL_INSTALL_SCRIPT')) {
	// link to installer
	die("You cannot request this file directly, please use <a href=\"index.php\">the installer</a>");
}

$errors = array();
$vars['db_connect_error'] = false;
$vars['sqltype_error'] = false;
$vars['sqluser_error'] = false;
$vars['db_exists'] = false;
$vars['dbname_empty'] = false;
$vars['db_create_error'] = false;
$vars['check_create_db'] = 'checked';
$vars['table_create_error'] = false;
$vars['sqlType'] = 'mysql';
$vars['sql_pass'] = '';


// If the form from Step 2 has been submitted
// we need to process it
if (isset($_POST['submit'])) {
    
	// Verify the submitted data
	$sqlType = $_POST['sqlType'];
	
	// We only require these settings for MySQL
	if ($sqlType == 'mysql') {
		$sqlUser = $_POST['sqluser'];
		$sqlPass = $_POST['sqlpass'];
		$sqlHost = $_POST['sqlhost'];
		$dbName  = $_POST['dbname'];
		
		if (empty($sqlUser))
			$errors['sqluser_error'] = true;

		if (empty($sqlHost))
			$sqlHost = 'localhost';
	
		if (empty($dbName))
			$errors['dbname_empty'] =  true;
			
	} else {
		$dbName = dirname(dirname(__FILE__)) . '/sqlite/atmail.db';
		
		if (!createSQLiteDir()) {
			die('failed to create sqlite dir!');
		}
	}
	
	// We support mysql and sqlite at the moment
	if ($sqlType != 'mysql' && $sqlType != 'sqlite')
		$errors['sqltype_error'] = '<span class="error">Invalid SQL type selected</span>';

	// Save data if there are no errors
	if (!count($errors)) {
	    
		// Store values in $_SESSION['pref'] for writing to
		// Config.php at end of install
		$_SESSION['pref']['sql_type']  = $sqlType;
		$_SESSION['pref']['sql_user']  = $sqlUser;
		$_SESSION['pref']['sql_host']  = $sqlHost;
		$_SESSION['pref']['sql_pass']  = $sqlPass;
		$_SESSION['pref']['sql_table'] = $dbName;

        // MySQL
        if ($sqlType == 'mysql') {
        	            
        	// Attempt connection to SQL server
        	set_include_path('../' . PATH_SEPARATOR . get_include_path());
        	require_once('../library/Zend/Db/Adapter/Pdo/Mysql.php');
            
            try {
                if (isset($_POST['create_db']) && $_POST['create_db']) {
                    
                    // Try to create DB if it doesn't exist

                    if (preg_match('/[^a-z0-9_\-]+/', $dbName)) {
                        throw new Zend_Exception('Invalid database name. Use only letters, numbers, - and _');
                    }
                    
                    $db = new Zend_Db_Adapter_Pdo_Mysql(
                        array(
                            'host'     => $sqlHost,
                            'username' => $sqlUser,
                            'password' => $sqlPass,
                            'dbname'   => ''
                        )
                    );
                    
                    $db->getConnection()->exec("create database `$dbName`");
                    $db->getConnection()->exec("use $dbName");
                        
                } else {
                    $db = new Zend_Db_Adapter_Pdo_Mysql(
                        array(
                            'host'     => $sqlHost,
                            'username' => $sqlUser,
                            'password' => $sqlPass,
                            'dbname'   => $dbName
                        )
                    );            
                }

			    $db->getConnection();
			    
            } catch (Zend_Db_Adapter_Exception $e) {
                $errors['db_connect_error'] = $e->getMessage();   
            } catch (Zend_Exception $e) {
                $errors['db_connect_error'] = $e->getMessage();
            } catch (PDOException $e) {
                $errors['db_exists'] = 1;
            }

            if (!count($errors)) {
                // Create the dbconfig.ini
                $configFile = file_get_contents('../config/dbconfig.ini.default');
                $configFile = preg_replace('/^(database\.params\.host\s*=).*?$/m',     '$1 "' . $_SESSION['pref']['sql_host'] . '"',  $configFile);  
                $configFile = preg_replace('/^(database\.params\.username\s*=).*?$/m', '$1 "' . $_SESSION['pref']['sql_user'] . '"',  $configFile);  
                $configFile = preg_replace('/^(database\.params\.password\s*=).*?$/m', '$1 "' . $_SESSION['pref']['sql_pass'] . '"',  $configFile);  
                $configFile = preg_replace('/^(database\.params\.dbname\s*=).*?$/m',   '$1 "' . $_SESSION['pref']['sql_table'] . '"', $configFile);  
                file_put_contents('../config/dbconfig.ini', $configFile);
                
                // Make dbconfig.ini only readable/writable by owner/group
                chmod(dirname(dirname(__FILE__)) . '/config/dbconfig.ini', 0640);
            }
            
			if (!count($errors) && isset($_POST['create_tables']) && $_POST['create_tables']) {
			    
			    try {
    				$tablesCreated = array();

    				// Populate the Atmail DB
    				$file = file('atmail7.sql');
    	            
    				foreach ($file as $line) {
    				    
    					$line = trim($line);
    	
    					// ignore comments and empty lines
    					if (preg_match('/^[\-#]+/', $line) || empty($line))
    						continue;
    
    			        if (preg_match('/^\/\*/', $line) || empty($line))
                            continue;
    	
    					// If we find the end of an sql statement
    					// append the line to $sql and execute it
    					if (preg_match('/;$/', $line)) {
    					    
    						$sql .= "$line\n";

    						$res = $db->getConnection()->exec($sql);
    					}
    					// If we find the beginning of a statement
    					// reset $sql to $line
    					elseif (preg_match('/CREATE TABLE `?([a-z_]+)`?/i', $line, $m)) {
    						$sql = "$line\n";
    						$tablesCreated[] = $m[1];
    					} elseif (preg_match('/^(CREATE|INSERT)/', $line)) {
    						$sql = "$line\n";
    					}
    	
    					// Otherwise it must be more of the same statement
    					// so append it to $sql
    					else
    						$sql .= "$line\n";
    				}
    				
    				try {
    				    $contents = file_get_contents('atmail7-default-config.sql');
						$sqls = explode(';', $contents);
						foreach($sqls as $sql)
						{
							$res = $db->getConnection()->exec($sql);
						}
    				} catch (PDOException $e) {
    				    // silent fail   
    				}
    				
    				// Create the default user group
    				$db->getConnection()->exec("INSERT IGNORE INTO `Groups` 
							( `GroupName` , `GroupDescription` , `POP3Support` , `IMAPSupport` , `GroupwareZone` , `Webmail` , `Calendar` , `SharedAbook` , `Sync`, `WebSyncShared`, `WebSyncGlobal` , `CalDAVServer`, `CardDAVServer`)
							VALUES 
							( 'default', 'Default domain group settings', '1', '1', 'System', '1', '1', '1', '1', '1', '1', '1', '1' )");
                    
    			} catch (PDOException $e) {

    				$errors['table_create_error'] = $e->getMessage();
    
    				// Remove the last table from the array as this
    				// is the one the error occured on it was not created
    				$trash = array_pop($tablesCreated);
    
    				// Now clean up, removing all the tables created
    				// to this point
    				foreach ($tablesCreated as $table)
    					$db->getConnection()->exec("DROP TABLE $table");
    
	    			}
			}
        } /*elseif ($sqlType == 'sqlite') {
            
        	// Back up any existing DB, just in case
        	if (file_exists($dbName)) {
        		rename($dbName, $dbName.'-'.time().'.bak');
        	}
        	
            $db = DB::connect("sqlite:///$dbName");

	        if (DB::isError($db)) {
	        	$errors['db_connect_error'] = $db->getDebugInfo();
	        } else {
	      		$schema = dirname(__FILE__) . '/atmail.sqlite';
	      		$query = file_get_contents($schema);
	        	$res = sqlite_exec($query, $db->connection);
	        	
	        	if ($res === false) {
	        		$errors['table_create_error'] = sqlite_last_error($db->connection);
	        		unlink('../sqlite/atmail.db');
	        	}
	        }
        }*/

		if (!count($errors))
		{
			gotoStep(3);
		}
	}
}

// Print the step 2 page if no data submitted yet
// or there were errors in submitted data

// merge any pref values into $vars so if we are
// returning from a latter step the values are auto
// completed
if (isset($_SESSION['pref']['sql_type']))
	$vars = array_merge($vars, $_SESSION['pref']);

// Create some default values
$vars['sql_host'] = isset($sqlHost) ? $sqlHost : 'localhost';

// If running Darwin, mysql does not accept connections on localhost, needs 127.0.0.1
if(PHP_OS == 'Darwin')
    $vars['sql_host'] = '127.0.0.1';

if (!isset($vars['sql_table']) && !isset($errors['db_exists'])) {
	$vars['sql_table'] = 'atmail';
}

$vars['check_create_tables'] = (isset($_REQUEST['submit']) && !isset($_REQUEST['create_tables'])) ? '' : 'checked';

if(!isset($vars['sql_user']))
    $vars['sql_user'] = 'root';

$vars['output'] = parse("$htmlPath/step2.phtml", array_merge($vars, $errors));

if (isset($_SESSION['pref']['sql_type'])) {
	$vars['output'] = str_replace("<option value=\"{$vars['output']}\">",
								  "<option value=\"{$vars['output']}\" selected>",
								  $vars['output']);
}


function createSQLiteDir()
{
	if (!is_dir('../sqlite')) {
		if (!mkdir('../sqlite')) {
			return false;	
		}
	}
	
	if (file_exists('../sqlite/.htaccess')) {
		return true;
	}
	
	$htaccess = <<<EOF
order deny, allow
deny from all
EOF;
	
	if ($fh = fopen('../sqlite/.htaccess', 'w')) {
		if (fwrite($fh, $htaccess) == strlen($htaccess)) {
			$return = true;
		} else {
			$return = false;
		}
	} else {
		$return = false;
	}
	
	fclose($fh);
	return $return;
}
