<?php
error_reporting(E_ERROR);
define("G_MAXIMUMQUERYSIZE", 1000000);                                    //Maximum query size is 1M. Lower it in case of query problems

//(int)ini_get("memory_limit") < 128 ? ini_set("memory_limit", "128M") : null;
ini_set("memory_limit", "-1");
ini_get("max_execution_time") < 600 ? ini_set("max_execution_time", "600") : null;
$path = "../../libraries/";
ini_set('include_path', $path.'../PEAR/');
if (!is_writable($path.'smarty/')) {
    echo "Directory <b>".realpath($path.'smarty/')."</b> must be writable by the server in order to continue";
    exit;
}

if (is_file($path."smarty/smarty_config.php") && is_file($path."language/lang-english.php")) {                        //Check if smarty and language file exist, and halt program execution if it is not present
    /**The smarty libraries*/
    require_once $path."smarty/smarty_config.php";
    require_once $path."language/lang-english.php";
} else {
    echo "Mandatory files not found!";
    exit;
}
isset($_GET['upgrade']) ? $upgrade = '&upgrade=1' : $upgrade = '';
isset($_GET['migrate']) ? $migrate = '&migrate=1' : $migrate = '';

$message = '';$message_type = '';                                       //Initialize message variables

if (isset($_GET['step']) && $_GET['step'] >= 2) {                       //This inclusions are made only after we have made sure that they will work; that is, they are made after step 1
    /** HTML_QuickForm Class*/
    require_once 'HTML/QuickForm.php';
    /** HTML_QuickForm Smarty renderer class*/
    require_once 'HTML/QuickForm/Renderer/ArraySmarty.php';
    /**ADODB database abstraction class*/
    require_once($path.'adodb/adodb.inc.php');
    /**ADODB exceptions class*/
    require_once($path.'adodb/adodb-exceptions.inc.php');
    /**Various tools*/
    require_once($path.'tools.php');

    $ADODB_CACHE_DIR = $path."adodb/cache";                             //Initialize ADODB
    $ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
}

if (is_file($path.'configuration.php')) {
    $file_contents = file_get_contents($path.'configuration.php');
    preg_match('/define\("G_VERSION_NUM",\s"(.*)"\);/',   $file_contents, $version_num);
    if (isset($version_num[1])) {
        $version_num = $version_num[1];
    }
}
$d = dir ($path.'../backups/');                                         //Check if there is a failed installation folder left over
while (false !== ($entry = $d -> read())) {
    if (is_dir($path.'../backups/'.$entry) && preg_match('/(.+)_\d{10}/', $entry, $matches)) {
        $failed_upgrades[] = array('name' => $matches[1], 'date' => filemtime($path.'../backups/'.$entry), 'file' => $entry);
        $smarty -> assign("T_FAILED_UPGRADES", $failed_upgrades);
    }
}
$d -> close();

//Read the current version
$file_contents = file_get_contents('sample_config.php');
preg_match('/define\("G_VERSION_NUM",\s"(.*)"\);/', $file_contents, $matches);
isset($matches[1]) ? $smarty -> assign("T_VERSION", $matches[1]) : null;


/*
Restore data for unfinished upgrades.
During upgrade, an automatic backup is done. If an unexpected/unrecoverable error occurs (i.e. the user closes the browser)
the system might be in an error state. In this case, a message is displayed at the installation first page, where the user
may recover the previous data.
*/
if (isset($_GET['restore']) && is_dir($path.'../backups/'.$_GET['restore'])) {
    $d = dir ($path.'../backups/'.$_GET['restore']);                                         //Check if there is a failed installation folder left over
    while (false !== ($entry = $d -> read())) {
        if (is_file($path.'../backups/'.$_GET['restore'].'/'.$entry)) {
            $data[$entry] = unserialize(file_get_contents($path.'../backups/'.$_GET['restore'].'/'.$entry));
        }
    }
    $d -> close();

    /**Include database functions*/
    require_once($path."configuration.php");

    if (is_file($path.'../backups/'.$_GET['restore'].'/version.txt')) {
        $old_version = file_get_contents($path.'../backups/'.$_GET['restore'].'/version.txt');
        unset($data['version.txt']);                                                        //sql.txt was included to the database tables list
    }

    preg_match('/(.+)_\d{10}/', $_GET['restore'], $match);                                          //Get the database name from the filename

    $db -> NConnect($values['db_host'], $values['db_user'], $values['db_password'], $match[1]);     //Connect to the database specified by the backup file name
    if (version_compare($old_version, '3.1') > -1) {
        $db -> Execute("SET NAMES 'UTF8'");
    }

    $result = $db -> Execute("show tables");                                              //Get the database tables

    if (is_file($path.'../backups/'.$_GET['restore'].'/sql.txt')) {
        $sql = file_get_contents($path.'../backups/'.$_GET['restore'].'/sql.txt');
        $sql = explode(";\n", $sql);
        foreach ($sql as $query) {
        	$db -> Execute($query);
        }
        unset($data['sql.txt']);                                                        //sql.txt was included to the database tables list
    }
//echo "<pre>";
//print_r(array_keys($data));
//echo $sql;

    foreach ($data as $table => $value) {
        $db -> Execute("truncate table $table");

        for ($i = 0; $i < sizeof($data[$table]); $i++) {
            eF_insertTableData($table, $data[$table][$i]);
        }
    }

    $file_contents = file_get_contents($path.'configuration.php');
    preg_replace('/define\("G_VERSION_NUM",\s"(.*)"\);/', $old_version, $file_contents);
    file_put_contents($path.'configuration.php', $file_contents);

    $message = 'The restore process for '.$match[1].' database to previous version is complete and the configuration file was updated accordingly. You are strongly recommended to perform an upgrade whenever possible, since the system might have become unstable.';

} else if (isset($_GET['delete_backup']) && is_dir($path.'../backups/'.$_GET['delete_backup']) && strpos(realpath($path.'../backups/'.$_GET['delete_backup']), realpath($path.'../backups/')) !== false) {
    include_once($path."filesystem.php");
    eF_deleteFolder($path.'../backups/'.$_GET['delete_backup']);
    header("location:".$_SERVER['PHP_SELF']."?message=".urlencode('Backup data deleted successfully')."&message_type=success");
}

/*
The first step performs all the checks necessary to validate that efront may be installed correctly
There are 2 kinds of checks: For optional (recommended) settings, and for mandatory settings.
The former allow continuation of the installation process, while the latter may halt the installation,
if they are not met. The following checks are performed
- Software settings: Recomendation for installed software
- PHP Extensions: The Mandatory and Optional extensions
- PHP ini settings: Optional ini settings for optimal performance
- Permissions: The directories where eFront requires write access (Mandatory)
- PEAR packages: The PEAR packages that eFront relies upon are mandatory
- Local settings: Check for presence of language encodings (Optional)
*/
if (isset($_GET['step']) && $_GET['step'] == 1) {

    $php_version       = explode('.', phpversion());                    //Get PHP version
    $webserver         = explode(' ',$_SERVER['SERVER_SOFTWARE']);      //GET Server information from $_SERVER
    $webserver_type    = explode('/', $webserver[0]);                   //Extract server type from server information (e.g. "apache")
    $webserver_version = explode('.', $webserver_type[1]);              //Extract server version from server information (e.g. "2.2.4")

    $software['system'] = array('name'        => 'Platform',
                                'installed'   => $webserver[1] ? substr($webserver[1], 1, -1) : 'Unknown',
                                'recommended' => 'Any',
                                'status'      => true,
                                'help'        => 'eFront may be installed on systems running Microsoft Windows and on most Unix and Linux systems');
    $software['PHP']    = array('name'        => 'PHP',
                                'installed'   => phpversion(),
                                'recommended' => '5.2.0 or newer',
                                'status'      => isset($php_version[0]) && $php_version[0] <= 4 ? false : true,
                                'help'        => 'eFront is designed using PHP version 5.2.0. Usage of PHP version < 5.1 is not recommended, butt will work. PHP 4 is not supported');
    $software['apache'] = array('name'        => 'Web server',
                                'installed'   => $webserver[0],
                                'recommended' => 'Apache 2.x or newer',
                                'status'      => !strcasecmp($webserver_type[0], 'apache') && $webserver_version[0] >= 2 ? true : false,
                                'help'        => 'eFront is tested and known to work well with Apache 2 web server');
/*
    $software['MySQL']  = array('name'        => 'MySQL DBMS',
                                'installed'   => print_r(mysql_connect()),
                                'recommended' => '4.1.x, 5.x or newer',
                                'status'      => false,
                                'help'        => 'eFront is designed for optimal performance with MySQL 5, but it will work with MySQL 4 as well. No other databases are supported.');
*/

    $smarty -> assign("T_SOFTWARE", $software);                         //Software variables are Optional

    $extensions   = get_loaded_extensions();

    $mandatory['mbstring'] = array('enabled' => in_array('mbstring', $extensions),
                                   'name'    => 'MultiByte (UTF) Support',
                                   'help'    => 'This extension is mandatory since the system is designed to use UTF-8 character settings. If using windows, make sure that php_mbstring.dll extension is loaded inside the php.ini file. If using linux, make sure PHP is compiled with Multibyte support');
    $mandatory['session']  = array('enabled' => in_array('session', $extensions),
                                   'name'    => 'Session Support',
                                   'help'    => 'Sessions are mandatory in order for the system to operate');
    $mandatory['iconv']    = array('enabled' => in_array('iconv', $extensions),
                                   'name'    => 'Iconv Functions',
                                   'help'    => 'Iconv extension is needed in order to perform localization conversions');
    $mandatory['pcre']     = array('enabled' => in_array('pcre', $extensions),
                                   'name'    => 'POSIX Regular expressions',
                                   'help'    => 'Regular expressions are used thoroughly throughout the system');
    $mandatory['mysql']    = array('enabled' => in_array('mysql', $extensions),
                                   'name'    => 'MySQL support',
                                   'help'    => 'The system requires MySQL support. If using windows, make sure that php_mysql.dll extension is loaded inside the php.ini file. If using linux, make sure PHP is compiled with MySQL support');

    $optional['zip']  = array('enabled' => in_array('zip', $extensions),
                              'name'    => 'ZIP extension',
                              'help'    => 'ZIP extension is needed in order to use built-in compression functions');
    $optional['ldap'] = array('enabled' => in_array('ldap', $extensions),
                              'name'    => 'LDAP functions',
                              'help'    => 'LDAP extension is needed in case LDAP interoperability is needed');

    $smarty -> assign("T_MANDATORY", $mandatory);
    $smarty -> assign("T_OPTIONAL", $optional);

    $ini_settings = ini_get_all();

    $settings['register_globals']    = array('value'       => $ini_settings['register_globals']['global_value'] ? 'ON' : 'OFF',
                                             'recommended' => 'OFF',
                                             'status'      => $ini_settings['register_globals']['global_value'] ? 0 : 1,
                                             'name'        => 'register_globals',
                                             'help'        => 'For security reasons, register_globals must be set to OFF');
    $settings['safe_mode']           = array('value'       => $ini_settings['safe_mode']['global_value'] ? 'ON' : 'OFF',
                                             'recommended' => 'OFF',
                                             'status'      => $ini_settings['safe_mode']['global_value'] ? 0 : 1,
                                             'name'        => 'safe_mode',
                                             'help'        => 'safe_mode should be set to OFF in order for the platform to work correctly');
    $settings['file_uploads']        = array('value'       => $ini_settings['file_uploads']['global_value'] ? 'ON' : 'OFF',
                                             'recommended' => 'ON',
                                             'status'      => $ini_settings['file_uploads']['global_value'] ? 1 : 0,
                                             'name'        => 'file_uploads',
                                             'help'        => 'File uploads should be turned on');
    $settings['upload_max_filesize'] = array('value'       => $ini_settings['upload_max_filesize']['global_value'],
                                             'recommended' => '1M - 100M',
                                             'status'      => substr($ini_settings['upload_max_filesize']['global_value'], 0, -1) >= 1 && substr($ini_settings['upload_max_filesize']['global_value'], 0, -1) <= 100 ? 1 : 0,
                                             'name'        => 'upload_max_filesize',
                                             'help'        => 'Uploading maximum file size can be set to the most suitable value');
    $settings['post_max_size']       = array('value'       => $ini_settings['post_max_size']['global_value'],
                                             'recommended' => 'same or larger than upload_max_file_size',
                                             'status'      => $ini_settings['post_max_size']['global_value'] >= $ini_settings['upload_max_filesize']['global_value'] ? 1 : 0,
                                             'name'        => 'post_max_size',
                                             'help'        => 'Post_max_size should be set at least equal to upload_max_filesize');
    $settings['max_execution_time']  = array('value'       => $ini_settings['max_execution_time']['global_value'],
                                             'recommended' => '>120',
                                             'status'      => $ini_settings['max_execution_time']['global_value'] >= 120 ? 1 : 0,
                                             'name'        => 'max_execution_time',
                                             'help'        => 'Maximum script execution time can be set to the most suitable value');
    $settings['memory_limit']        = array('value'       => $ini_settings['memory_limit']['global_value'],
                                             'recommended' => '>32M',
                                             'status'      => substr($ini_settings['memory_limit']['global_value'], 0, -1) >= 32 ? 1 : 0,
                                             'name'        => 'memory_limit',
                                             'help'        => 'Memory limit must be set to a high value, at least 32MB, in order for efront to run');
    $settings['zlib.output_handler'] = array('value'       => $ini_settings['zlib.output_handler']['global_value'],
                                             'recommended' => 'Off',
                                             'status'      => $ini_settings['zlib.output_handler']['global_value'] ? 0 : 1,
                                             'name'        => 'zlib.output_handler',
                                             'help'        => 'Zlib output handler must not be enabled in order to transparently compress files at run-time');
    $settings['zlib.output_compression'] = array('value'   => $ini_settings['zlib.output_compression']['global_value'],
                                             'recommended' => 'Off',
                                             'status'      => $ini_settings['zlib.output_compression']['global_value'] ? 0 : 1,
                                             'name'        => 'zlib.output_compression',
                                             'help'        => 'Zlib output compression must not be enabled in order to transparently compress files at run-time');

    $smarty -> assign("T_SETTINGS", $settings);


    $permissions['www/content']                 = array('writable' => is_writable($path.'../www/content') && is_writable($path.'../www/content/lessons') && is_writable($path.'../www/content/admin'),
                                                        'help'     => 'This is the directory where the lesson content resides, and should be writable along with any subfolders');
    $permissions['www/css']                     = array('writable' => is_writable($path.'../www/css'),
                                                        'help'     => 'This directory is where custom CSS stylesheets are uploaded');
    $permissions['www/images/avatars']          = array('writable' => is_writable($path.'../www/images/avatars'),
                                                        'help'     => 'This is the directory where the user avatars are created');
    $permissions['www/images/logo']             = array('writable' => is_writable($path.'../www/images/logo'),
                                                        'help'     => 'This is the directory where custom site logos are uploaded');
    $permissions['libraries']                   = array('writable' => is_writable($path),
                                                        'help'     => 'libraries directory should be writable only during the installation process');
    $permissions['libaries/language']           = array('writable' => is_writable($path.'language'),
                                                        'help'     => 'This directory needs to writable, in order to be able to upload new language files or modify existing ones');
    $permissions['libaries/smarty/templates_c'] = array('writable' => is_writable($path.'smarty/templates_c'),
                                                        'help'     => 'This is the template caching directory');
    $permissions['libaries/smarty/cache']       = array('writable' => is_writable($path.'smarty/cache'),
                                                        'help'     => 'This is the template caching directory');
    $permissions['backups']                     = array('writable' => is_writable($path.'../backups'),
                                                        'help'     => 'In this directory all the system backups are stored');
    $permissions['upload']                      = array('writable' => is_writable($path.'../upload'),
                                                        'help'     => 'This is the directory where user related files are stored');
    $permissions['modules']                     = array('writable' => is_writable($path.'../modules'),
                                                        'help'     => 'This is the directory where modules are uploaded and installed');

    $smarty -> assign("T_PERMISSIONS", $permissions);

    $pear['PEAR.php']                                = array('exists' => ($f = fopen ('PEAR.php', 'r', true))                                ? true : false,
                                                             'help'   => 'PEAR libraries are mandatory in order for the system to function');
    $pear['HTML/QuickForm.php']                      = array('exists' => ($f = fopen ('HTML/QuickForm.php', 'r', true))                      ? true : false,
                                                             'help'   => 'This PEAR package is mandatory and the system will not work without it');
    $pear['HTML/QuickForm/Renderer/ArraySmarty.php'] = array('exists' => ($f = fopen ('HTML/QuickForm/Renderer/ArraySmarty.php', 'r', true)) ? true : false,
                                                             'help'   => 'This PEAR package is mandatory and the system will not work without it');
    $pear['Mail.php']                                = array('exists' => ($f = fopen ('Mail.php', 'r', true)) ? true : false,
                                                             'help'   => 'This PEAR Mail package is is needed in order for the system to be able to send emails');
    $pear['Net/SMTP.php']                            = array('exists' => ($f = fopen ('Net/SMTP.php', 'r', true)) ? true : false,
                                                             'help'   => 'This PEAR Net_SMTP package is is needed in order for the system to be able to send emails');
    $pear['Net/Socket.php']                          = array('exists' => ($f = fopen ('Net/Socket.php', 'r', true)) ? true : false,
                                                             'help'   => 'This PEAR Net_Socket package is is needed in order for the system to be able to send emails');
    fclose($f);

    $smarty -> assign("T_PEAR", $pear);

//    $languages = array_values(array_filter(scandir($path.'language/'), create_function('$a', 'return strpos($a, "lang") !== false;')));     //Get the language files that reside inside the 'language' directory

    $greek_tags = array('greek', 'el_EL', 'el_el', 'Greek', 'gr_gr', 'el_gr', 'el-el', 'el-EL', 'el-gr', 'gr-gr', 'en_US.utf8');
    while (!setlocale(LC_ALL, $tag = $greek_tags[0])) {
        array_shift($greek_tags);
    }
    $locale['greek']   = array('language' => 'greek',                               //To see the system installed locales, type locale-a in command prompt (linux/unix).
                               'locale'   => sizeof($greek_tags) > 0 ? (setlocale(LC_ALL, $tag)) : '',
                               'help'     => 'Your system should support Greek language in order to use Greek language in the system');
    if ($tag) {
        $file = file_get_contents($path."language/lang-greek.php");
        $file = preg_replace("/(define\(\"_HEADERLANGUAGETAG\",\").*(\"\);)/", '$1'.$tag.'$2', $file);
        file_put_contents($path."language/lang-greek.php", $file);
    }

    $english_tags = array('english', 'en_US', 'en_us', 'English', 'en_EN', 'en_en', 'en-us', 'en-US', 'en-en', 'en-EN', 'en_US.utf8');

    while (!setlocale(LC_ALL, $tag = $english_tags[0])) {
        array_shift($english_tags);
    }
    $locale['english'] = array('language' => 'english',
                               'locale'   => sizeof($english_tags) > 0 ? (setlocale(LC_ALL, $tag)) : '',
                               'help'     => 'Your system should support English language in order to use the system');
    if ($tag) {
        $file = file_get_contents($path."language/lang-english.php");
        $file = preg_replace("/(define\(\"_HEADERLANGUAGETAG\",\").*(\"\);)/", '$1'.$tag.'$2', $file);
        file_put_contents($path."language/lang-english.php", $file);
    }


    $smarty -> assign("T_LOCALE", $locale);

    $install = true;                                            //The install variable will be used to check whether any mandatory setting is not met.
    foreach ($mandatory as $key => $value) {                    //Check mandatory PHP extensions
        if (!$value['enabled']) {
            $install = false;
        }
    }
    foreach ($permissions as $key => $value) {                  //Check filesystem permissions
        if (!$value['writable']) {
            $install = false;
        }
    }
    foreach ($pear as $key => $value) {                         //Check PEAR packages
        if (!$value['exists']) {
            $install = false;
        }
    }
    if ($php_version[0] <= 4) {                                 //PHP 4 will not run
        $install = false;
    }
    if (!$settings['memory_limit']['status']) {                 //Memory size must be above a specific threshold
        $install = false;
    }

    if (!$upgrade && !$migrate) {
        $smarty -> assign("T_CONFIGURATION_EXISTS", is_file($path.'configuration.php'));

        require_once($path.'filesystem.class.php');
        require_once($path.'tree.class.php');
        require_once($path.'filesystem3.class.php');
        $lesson_folders = EfrontFileSystem :: filterFiles(scandir($path.'../www/content/lessons/'));
        $user_folders   = EfrontFileSystem :: filterFiles(scandir($path.'../upload/'), false, array('htaccess'));

        if (sizeof($lesson_folders) > 0 || sizeof($user_folders) > 0) {
            $smarty -> assign("T_NON_EMPTY_FOLDERS", true);
        }
    }
    $smarty -> assign("T_INSTALL", $install);

    //Check if we are installing over an existing installation and display appropriate message


}

/*
The second step has to do with database settings and creation. The user inserts database parameters,
checks if they are correct and then creates the database itself. since we got here from the previous step,
we can be sure that all mandatory elements are present, so we may use them (for example adodb, quickform etc)
There are 3 different cases in this step. The first one concerns the clean installation, and the user
only specifies the database connection settings. The second case is when the user is performin an upgrade.
In this case, the database connection settings are read from the existing configuration file, and the
Old database is deleted. The third case is when the user is migrating. In this case, he fills in both
the existing database connection settings, as well as the new database connection settings. Yhe new database
is created and then all values from the old database are copied to the new one.
*/
else if (isset($_GET['step']) && $_GET['step'] == 2) {

    $form = new HTML_QuickForm("step2_form", "post", $_SERVER['PHP_SELF']."?step=2".$upgrade.$migrate, "", null, true);
    $form -> registerRule('checkParameter', 'callback', 'eF_checkParameter');                   //Register this rule for checking user input with our function, eF_checkParameter

    if (isset($_GET['upgrade']) || isset($_GET['migrate'])) {

        if (isset($_GET['upgrade'])) {
            $form -> addElement('select', 'db_type', null, array('mysql' => 'MySQL'));
            $form -> addRule('db_type', 'The database type is mandatory', 'required', null, 'client');                //The database type can only be string and is mandatory
            $form -> addRule('db_type', 'Invalid database type', 'checkParameter', 'string');                //The database type can only be string and is mandatory

            $form -> addElement('text', 'db_host', null, 'class = "inputText"');
            $form -> addRule('db_host', 'The database host is mandatory', 'required', null, 'client');                //The database type can only be string and is mandatory
            $form -> addRule('db_host', 'Invalid database host', 'checkParameter', 'alnum_general');         //The database host can only be string and is mandatory

            $form -> addElement('text', 'db_user', null, 'class = "inputText"');
            $form -> addRule('db_user', 'The database user is mandatory', 'required', null, 'client');                //The database type can only be string and is mandatory
            $form -> addRule('db_user', 'Invalid database user', 'checkParameter', 'alnum_general');                //The database user can only be string

            $form -> addElement('password', 'db_password', null, 'class = "inputText"');

            $form -> addElement('text', 'db_name', null, 'class = "inputText"');
            $form -> addRule('db_name', 'The database name is mandatory', 'required', null, 'client');                //The database type can only be string and is mandatory
            $form -> addRule('db_name', 'Invalid database name', 'checkParameter', 'alnum_general');        //The database name can only be string

            $form -> addElement('text', 'new_db_name', null, 'class = "inputText"');
            $form -> addRule('new_db_name', 'Invalid database name', 'checkParameter', 'alnum_general');        //The database name can only be string

            $form -> addElement('submit', 'check_database', 'Check Database settings', 'class = "flatButton"');
            $form -> addElement('submit', 'create_database', 'Create database', 'class = "flatButton"');
            $form -> addElement('submit', 'create_tables', 'Create database tables', 'class = "flatButton"');
            $form -> addElement('submit', 'rollback', 'Delete database and retry', 'class = "flatButton" onclick = "return confirm(\'This way all existing data in the new database will be lost. Are you sure?\')"');
            $form -> addElement('submit', 'step2_submit', 'Continue to next step', 'class = "flatButton"');

            if (is_file($path.'configuration.php')) {
                $file_contents = file_get_contents($path.'configuration.php');                            //Load existing configuration file

                preg_match('/define\("G_DBHOST", "(.*)"\);/',   $file_contents, $host);
                preg_match('/define\("G_DBUSER", "(.*)"\);/',   $file_contents, $user);
                preg_match('/define\("G_DBPASSWD", "(.*)"\);/', $file_contents, $password);
                preg_match('/define\("G_DBNAME", "(.*)"\);/',   $file_contents, $name);
                $form -> setDefaults(array('db_host'     => $host[1],
                                           'db_user'     => $user[1],
                                           'db_password' => $password[1],
                                           'db_name'     => $name[1]));
            }
        } elseif (isset($_GET['migrate'])) {
            $form -> addElement('select', 'db_type', null, array('mysql' => 'MySQL'));
            $form -> addRule('db_type', 'The source database type is mandatory', 'required', null, 'client');                //The database type can only be string and is mandatory
            $form -> addRule('db_type', 'Invalid database type', 'checkParameter', 'string');                //The database type can only be string and is mandatory

            $form -> addElement('text', 'db_host', null, 'class = "inputText"');
            $form -> addRule('db_host', 'The source database host is mandatory', 'required', null, 'client');                //The database type can only be string and is mandatory
            $form -> addRule('db_host', 'Invalid database host', 'checkParameter', 'alnum_general');         //The database host can only be string and is mandatory

            $form -> addElement('text', 'db_user', null, 'class = "inputText"');
            $form -> addRule('db_user', 'The source database user is mandatory', 'required', null, 'client');                //The database type can only be string and is mandatory
            $form -> addRule('db_user', 'Invalid database user', 'checkParameter', 'alnum');                //The database user can only be string

            $form -> addElement('password', 'db_password', null, 'class = "inputText"');

            $form -> addElement('text', 'db_name', null, 'class = "inputText"');
            $form -> addRule('db_name', 'The source database name is mandatory', 'required', null, 'client');                //The database type can only be string and is mandatory
            $form -> addRule('db_name', 'Invalid database name', 'checkParameter', 'alnum_general');        //The database name can only be string

            $form -> addElement('text', 'dir', null, 'class = "inputText"');
            $form -> addRule('dir', 'The source directory name is mandatory', 'required', null, 'client');                //The database type can only be string and is mandatory

            $form -> addElement('select', 'new_db_type', null, array('mysql' => 'MySQL'));
            $form -> addRule('new_db_type', 'The target database type is mandatory', 'required', null, 'client');                //The database type can only be string and is mandatory
            $form -> addRule('new_db_type', 'Invalid database type', 'checkParameter', 'string');                //The database type can only be string and is mandatory

            $form -> addElement('text', 'new_db_host', null, 'class = "inputText"');
            $form -> addRule('new_db_host', 'The target database host is mandatory', 'required', null, 'client');                //The database type can only be string and is mandatory
            $form -> addRule('new_db_host', 'Invalid database host', 'checkParameter', 'alnum_general');         //The database host can only be string and is mandatory

            $form -> addElement('text', 'new_db_user', null, 'class = "inputText"');
            $form -> addRule('new_db_user', 'The target database user is mandatory', 'required', null, 'client');                //The database type can only be string and is mandatory
            $form -> addRule('new_db_user', 'Invalid database user', 'checkParameter', 'alnum');                //The database user can only be string

            $form -> addElement('password', 'new_db_password', null, 'class = "inputText"');

            $form -> addElement('text', 'new_db_name', null, 'class = "inputText"');
            $form -> addRule('new_db_name', 'The target database name is mandatory', 'required', null, 'client');                //The database type can only be string and is mandatory
            $form -> addRule('new_db_name', 'Invalid database name', 'checkParameter', 'alnum_general');        //The database name can only be string

            $form -> addElement('text', 'new_dir', null, 'class = "inputText"');
            $form -> addRule('new_dir', 'The target directory name is mandatory', 'required', null, 'client');                //The database type can only be string and is mandatory

            $form -> addElement('submit', 'check_database', 'Check Source Database settings', 'class = "flatButton"');
            $form -> addElement('submit', 'create_tables', 'Create database tables', 'class = "flatButton"');
            $form -> addElement('submit', 'rollback', 'Roll back', 'class = "flatButton"');
            $form -> addElement('submit', 'create_database', 'Continue', 'class = "flatButton"');
            $form -> addElement('submit', 'step2_submit', 'Continue', 'class = "flatButton"');

            $form -> setDefaults(array('new_dir' => strtr(realpath($path.'..'), '\\', '/')));
        }

        /*
        Perform the DBMS functions. Below, when we refer to "DBMS" we mean the software (e.g. MySQL)
        and by saying "database" we mean the specific database, e.g. "efront"
        */
        if ($form -> isSubmitted()) {
            if ($form -> validate()) {
                $values = $form -> exportValues();
                $db = ADONewConnection($form -> exportValue('db_type'));                                    //Set Connection parameter to "mysql"

                if (isset($_GET['migrate']) && !is_dir($values['dir'])) {
                    //$smarty -> assign("T_FILESERROR", 'Directory '.$values['dir'].' not found');
                    $message      .= 'Directory '.$values['dir'].' not found'."<br/>";
                    $message_type = 'failure';
                    $errors       = true;
                } elseif(isset($_GET['migrate']) && !is_dir($values['new_dir'])) {
                    //$smarty -> assign("T_FILESERROR", 'Directory '.$values['new_dir'].' not found');
                    $message      .= 'Directory '.$values['new_dir'].' not found'."<br/>";
                    $message_type = 'failure';
                    $errors       = true;
                } elseif (isset($values['create_tables']) || isset($values['rollback'])) {
                    if (isset($values['rollback'])) {
                        try {
                            if ($values['new_db_name'] && $values['new_db_name'] != $values['db_name']) {
                                $db -> NConnect($values['db_host'], $values['db_user'], $values['db_password']);
                                $db -> Execute("drop database ".$values['new_db_name']);
                            }
                        } catch (Exception $e) {
                            $message      = $e -> msg."<br/>";
                            $message_type = 'failure';
                        }
                    }

//Script for displaying progress bar
echo '
<base href = "'.dirname(dirname('http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'])).'/'.'" />
<script src = "js/eFrontScripts.js" ></script>
<link rel = "stylesheet" type = "text/css" href = "css/css_global.php" />
<table id = "popup_table" class = "divPopup" style = "display:none;">
    <tr class = "defaultRowHeight">
        <td class = "topTitle" id = "popup_title"></td>
        <td class = "topTitle" style = "width:1%;"><img src = "images/16x16/error.png" alt = "'._CLOSE.'" name = "" id = "popup_close" title = "'._CLOSE.'" onclick = "eF_js_showDivPopup(\'\', \'\', this.name)"/>
    </td></tr>
    <tr><td colspan = "2" id = "popup_data" style = "vertical-align:top;"></td></tr>
    <tr><td colspan = "2" id = "frame_data" style = "width:100%;height:100%">
        <iframe name = "POPUP_FRAME" id = "popup_frame" src = "about:blank" style = "border-width:0px;width:100%;height:100%;padding:0px 0px 0px 0px">Sorry, but your browser needs to support iframes to see this</iframe>
    </td></tr>
</table>

<div id="dimmer" class = "dimmerDiv" style="display:none;"></div>
<div id = "progress_table" style = "display:none">
<table style = "margin-left:100px;margin-top:20px;" align = "left">
    <tr><td>
        <span id = "border"   style = "position:absolute;text-align:center;width:100px;border:1px solid #d3d3d3;vertical-align:middle;z-index:2;margin-left:auto;margin-right:auto">0%</span>
        <span id = "progress" style = "background-color:#A0BDEF;width:0px;border:1px dotted #d3d3d3;position:absolute;margin-left:auto;margin-right:auto">&nbsp;</span>
    </td></tr>
</table>
</div>
<script>eF_js_showDivPopup("Progress", new Array("300px", "100px", "string"), "progress_table");</script>
<script>
function advanceProgress(x) {
    if (x > 0 && x < 100) {
        obj1 = document.getElementById("progress");
        obj2 = document.getElementById("border");
        current_progress = parseInt(obj1.style.width);
        if (current_progress < 100) {
            obj1.style.width = parseInt(obj1.style.width)+x+"px";
            obj2.innerHTML = parseInt(obj2.innerHTML)+x+"%";
        }
    } else if (x == 100) {
        document.getElementById("progress").style.width = 100 + "px";
        document.getElementById("border").innerHTML     = 100 + "%";
    }
}
</script>
';
ob_flush();
flush();
sleep(1);   //use this to make sure that the script initializes correctly, otherwise it may not work

                    if (isset($values['new_db_name']) && $values['new_db_name'] != $values['db_name']) {
                        try {
                            $db -> NConnect($values['db_host'], $values['db_user'], $values['db_password']);
                            $db -> Execute("SET NAMES 'UTF8'");
                            $db -> Execute("create database ".$values['new_db_name']." DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci");                          //Create the new database
                        } catch (Exception $e) {}
                    }

                    try {
                        $db -> NConnect($values['db_host'], $values['db_user'], $values['db_password'], $values['db_name']);
                        if (version_compare($version_num, '3.1') > -1) {
                            $db -> Execute("SET NAMES 'UTF8'");
                        }

                        $file_contents          = file_get_contents('sample_config.php');                    //Load sample configuration file
                        $existing_file_contents = file_get_contents($path.'configuration.php');              //Load existing configuration file

                        preg_match('/define\("G_SERVERNAME", "(.*)"\);/', $existing_file_contents, $servername);        //Get the server name, port and root path from the existing configuration
                        preg_match('/define\("G_SERVERPORT", "(.*)"\);/', $existing_file_contents, $serverport);
                        preg_match('/define\("G_ROOTPATH", "(.*)"\);/',   $existing_file_contents, $rootpath);

                        $patterns = array('/(define\("G_DBTYPE", ").*("\);)/',
                                          '/(define\("G_DBHOST", ").*("\);)/',
                                          '/(define\("G_DBUSER", ").*("\);)/',
                                          '/(define\("G_DBPASSWD", ").*("\);)/',
                                          '/(define\("G_DBNAME", ").*("\);)/',
                                          '/(define\("G_SERVERNAME", ").*("\);)/',
                                          '/(define\("G_SERVERPORT", ").*("\);)/',
                                          '/(define\("G_ROOTPATH", ").*("\);)/');

                        if (isset($_GET['migrate'])) {
                            $replacements = array('${1}'.$values['new_db_type'].'${2}',
                                                  '${1}'.$values['new_db_host'].'${2}',
                                                  '${1}'.$values['new_db_user'].'${2}',
                                                  '${1}'.$values['new_db_password'].'${2}',
                                                  '${1}'.$values['new_db_name'].'${2}',
                                                  '${1}'.rtrim($servername[1], "/")."/".'${2}',
                                                  '${1}'.$serverport[1].'${2}',
                                                  '${1}'.$rootpath[1].'${2}');
                        } else {
                            $replacements = array('${1}'.$values['db_type'].'${2}',
                                                  '${1}'.$values['db_host'].'${2}',
                                                  '${1}'.$values['db_user'].'${2}',
                                                  '${1}'.$values['db_password'].'${2}',
                                                  '${1}'.($values['new_db_name'] ? $values['new_db_name'] : $values['db_name']).'${2}',
                                                  '${1}'.rtrim($servername[1], "/")."/".'${2}',
                                                  '${1}'.$serverport[1].'${2}',
                                                  '${1}'.$rootpath[1].'${2}');
                        }

                        $new_file_contents = preg_replace($patterns, $replacements, $file_contents, -1, $limit);    //Replace sample settings with current settings
                        file_put_contents($path.'configuration_temp.php', $new_file_contents);                      //Create a temporary configuration file, which will be used throughout the rest of the installation

                        $result = $db -> Execute("show table status");                                              //Get the database tables

                        while (!$result->EOF) {
                            $tables[] = $result -> fields['Name'];
                            $result -> MoveNext();
                        }

                        /**Include the new configuration*/
                        require_once($path."configuration_temp.php");
                        /**Include database functions*/
                        require_once($path."database.php");

                        if ($values['new_db_name']) {                               //Connect to the old database again, since the above inclusion connected us to the new one
                            $db -> NConnect($values['db_host'], $values['db_user'], $values['db_password'], $values['db_name']); //Connect to the old database, because inclusion of database.php connected us to the new database
                        } else {
                            $backup_folder = $path.'../backups/'.$values['db_name'].'_'.time().'/';                                                                //Mark the installation time, in order to take backup
                            mkdir($backup_folder);
                        }
                        if (version_compare($version_num, '3.1') > -1) {
                            $db -> Execute("SET NAMES 'UTF8'");
                        }

                        if (!isset($version_num) && sizeof(eF_getTableData("configuration", "value", "name='caching'")) > 0) {          //Check of current version is 3+
                            $version_num = 3;
                        }

                        foreach ($tables as $table) {                                                           //We use a separate loop step here, in order to first read the entire existing database into memory, and create in a successive loop the new tables. This way in case the creation fails, we will not loose any data
                        	$data[$table]   = eF_getTableData($table, "*");
                            if (!$values['new_db_name']) {
                                file_put_contents($backup_folder.$table, serialize($data[$table]));
                                $result       = $db -> Execute("show create table $table");
                                $temp         = $result -> GetAll();
                                $definition[] = "drop table ".$temp[0]['Table'];
                                $definition[] = $temp[0]['Create Table'];
                            }
                            if (version_compare($version_num, 3) == -1) {                                                                //Versions 3+ do not need character type conversion, since UTF-8 is used by default
                                for ($i = 0; $i < sizeof($data[$table]); $i++) {
                                    foreach ($data[$table][$i] as $key => $value) {
                                        if (mb_detect_encoding($value, 'UTF-8, ISO-8859-7') == 'ISO-8859-7') {  //Check if the string needs conversion
                                            if ($table == 'questions' && $key == 'options') {
                                                $options = unserialize($value);
                                                for ($j = 0; $j < sizeof($options); $j++) {
                                                    $options[$j] = mb_convert_encoding($options[$j], 'UTF-8', array('UTF-8', 'ISO-8859-7'));
                                                }
                                                $value = serialize($options);
                                            }
                                            $data[$table][$i][$key] = mb_convert_encoding($value, 'UTF-8', array('UTF-8', 'ISO-8859-7'));
                                        }
                                    }
                                }
                            }
                            if (!$values['new_db_name']) {
                                $result = $db -> Execute("drop table $table");
                            }
                        }                        
                        //$data['cache'] = '';                                                               //Reset cache.
                        if (!$values['new_db_name']) {
                            file_put_contents($backup_folder.'sql.txt', implode(";\n", $definition));
                            file_put_contents($backup_folder.'version.txt', $version_num);
                        }

echo "<script>advanceProgress(10)</script>";
ob_flush();
flush();

                        $file_contents = trim(file_get_contents("sql_".$values['db_type'].".txt"));         //Get the sql queries text, trimmed
                        $file_contents = explode(';',$file_contents);                                       //Form the sql queries, by splitting each CREATE statement
                        if (!end($file_contents)) {
                            array_pop($file_contents);                                                      //Remove last element, if it is an empty array (which is usually the case)
                        }

                        if ($values['new_db_name']) {
                            $db -> NConnect($values['db_host'], $values['db_user'], $values['db_password'], $values['new_db_name']);
                            $db -> Execute("SET NAMES 'UTF8'");
                        }

                        foreach ($file_contents as $query) {                                                //Run queries
                            preg_match('/CREATE TABLE (\w+) .*/', $query, $matches);
                            $new_tables[] = $matches[1];                                                      //Store new database table names.
                            try {
                                $db -> Execute($query);
                            } catch (Exception $e) {
                                $failed_tables[] = $e -> msg;                                                 //Each failed query will not halt the execution, but will be recorded to this table
                            }
                        }
                        if (isset($failed_tables)) {                                                        //If there were any errors, assign them to smarty to be displayed
                            $message      .= implode(', ', $failed_tables)."<br/>";
                            $message_type = 'failure';
                            $errors       = true;
                        }

                        //Convert deprecated "system_announcements" table to news table
                        if (($key = array_search('system_announcements', $tables)) !== false) {
                            foreach ($data['system_announcements'] as $value) {
                                $value['lessons_ID'] = 0;
                                $data['news'][]      = $value;
                            }

                            unset ($tables[$key]);
                            $tables = array_values($tables);
                        }

                        $db -> Execute("SET NAMES 'UTF8'");

                        //Treat modules consistently
                        for ($i = 0; $i < sizeof($data['modules']); $i++) {
                            if (is_dir($path.'../modules/'.$data['modules'][$i]['name']) && is_file($path.'../modules/'.$data['modules'][$i]['name'].'/sql_mysql.txt') && in_array($data['modules'][$i]['name'], $tables)) {
                                $file_contents = file_get_contents($path.'../modules/'.$data['modules'][$i]['name'].'/sql_mysql.txt');
                                $db -> Execute($file_contents);
                                $new_tables[] = $data['modules'][$i]['name'];
                            }
                        }

                        //Update old forums
                        if (in_array('f_categories', $tables)) {
                            if (!in_array('f_forums', $tables)) {
                                $tables[]   = 'f_forums';
                            }
                            for ($i = 0; $i < sizeof($data['f_categories']); $i++ ) {
                                $f_forums[] = array("id"          => $data['f_categories'][$i]['id'],
                                                    "title"       => $data['f_categories'][$i]['title'],
                                                    "lessons_ID"  => $data['f_categories'][$i]['lessons_ID'],
                                                    "users_LOGIN" => 'admin',
                                                    "status"      => $data['f_categories'][$i]['status'],
                                                    "parent_id"   => 0,
                                                    "comments"    => $data['f_categories'][$i]['title']);
                            }
                            $f_forums[] = array("id"          => 0,
                                                "title"       => 'General forum',
                                                "lessons_ID"  => 0,
                                                "users_LOGIN" => 'admin',
                                                "status"      => 'public',
                                                "parent_id"   => 0,
                                                "comments"    => 'General forum');
                            $data['f_forums'] = $f_forums;

                            unset($data['f_categories']);
                            for ($i = 0; $i < sizeof($data['f_topics']); $i++ ) {
                                if (isset($data['f_topics'][$i]['f_categories_ID'])) {
                                    $data['f_topics'][$i]['f_forums_ID'] = $data['f_topics'][$i]['f_categories_ID'];
                                    unset($data['f_topics'][$i]['f_categories_ID']);
                                }
                            }
                            for ($i = 0; $i < sizeof($data['f_poll']); $i++ ) {
                                if (isset($data['f_topics'][$i]['f_categories_ID'])) {
                                    $data['f_poll'][$i]['f_forums_ID'] = $data['f_poll'][$i]['f_categories_ID'];
                                    unset($data['f_poll'][$i]['f_categories_ID']);
                                }
                            }
                        }

                        //Convert old files to new file system
                        if (sizeof($data['files']) == 0) {
                            $must_update_files = true;                                       //This switch notifies the system that filesystem needs upgrading. It will be used later.
/*
                            require_once($path."filesystem.class.php");
                            require_once($path.'tree.class.php');
                            require_once($path.'filesystem3.class.php');
                            try {
                                //$directory = new EfrontDirectory(G_ROOTPATH.'www/content/lessons/');
                                //$dirContents = $directory -> getContentsFS();
                                foreach ($it = new EfrontREFilterIterator(new RecursiveIteratorIterator(new RecursiveDirectoryIterator(G_LESSONSPATH), RecursiveIteratorIterator :: SELF_FIRST), array('/.svn/'), false) as $entry) {
                                   $data['files'][] = array('path'          => $entry,
                                                            'users_LOGIN'   => 'admin',
                                                            'timestamp'     => time(),
                                                            'description'   => basename($entry));
                                }
                                $tables[] = 'files';
                            } catch (Exception $e) {
                                $message      .= $e -> getMessage()."<br/>";
                                $message_type = 'failure';
                                $errors       = true;
                            }
*/
                        } 

                        

                        foreach ($tables as $table) {
                            if (in_array($table, $new_tables)) {
                                $table_fields = $db -> GetCol("describe $table");//pr($table_fields);

echo "<script>advanceProgress(1)</script>";
ob_flush();
flush();

                                $rows       = array();
                                $table_size = sizeof($data[$table]);
                                for ($i = 0; $i < $table_size; $i++) {
                                    if ($table == 'users') {                                                                                                                                
                                        //Remove deprecated users fields (by keeping only the needed ones)
                                        $fields['login']          = $data[$table][$i]['login'];
                                        $fields['password']       = $data[$table][$i]['password'];
                                        $fields['languages_NAME'] = $data[$table][$i]['languages_NAME'];
                                        $fields['name']           = $data[$table][$i]['name'];
                                        $fields['surname']        = $data[$table][$i]['surname'];
                                        $fields['email']          = $data[$table][$i]['email'];
                                        $fields['active']         = $data[$table][$i]['active'];
                                        $fields['comments']       = $data[$table][$i]['comments'];
                                        $fields['user_type']      = $data[$table][$i]['user_type'];
                                        $fields['timestamp']      = $data[$table][$i]['timestamp'];
                                        $fields['avatar']         = $data[$table][$i]['avatar'];

                                        //convert old avatars to new ones.
                                        if (!eF_checkParameter($fields['avatar'], 'id')) {
                                            if (!is_file($fields['avatar']) && is_file($rootpath[1].'www/images/avatars/'.$fields['avatar'])) {
                                                preg_match("/\d{10}_prefix_(.*)\.\w{3}/", $fields['avatar'], $matches);
                                                if ($matches[1] == $fields['login']) {
                                                    if (is_dir($rootpath[1].'upload/'.$fields['login'])) {
                                                        if (!is_dir($rootpath[1].'upload/'.$fields['login'].'/avatars')) {
                                                            mkdir($rootpath[1].'upload/'.$fields['login'].'/avatars', 0755);
                                                        }
                                                        if (is_dir($rootpath[1].'upload/'.$fields['login'].'/avatars')) {
                                                            rename($rootpath[1].'www/images/avatars/'.$fields['avatar'], $rootpath[1].'upload/'.$fields['login'].'/avatars/'.basename($fields['avatar']));
                                                        }
                                                        $fields['avatar'] = $rootpath[1].'upload/'.$fields['login'].'/avatars/'.basename($fields['avatar']);
                                                    }
                                                } else {
                                                    $fields['avatar'] = $rootpath[1].'www/images/avatars/'.$fields['avatar'];
                                                }
                                            } else {
                                                $fields['avatar'] = '';
                                            }
                                        }
                                                                                
                                        $data[$table][$i] = $fields;
                                        $temp[$fields['login']] = $fields['user_type'];						//$temp will be needed later at users_to_lessons fix 
                                    } elseif ($table == 'lessons') {                                        //Remove deprecated lesson fields
                                        unset($data[$table][$i]['colors']);
                                        //Tracking is always 1 now
                                        $options = unserialize($data[$table][$i]['options']);                                        
                                        if (is_array($options) && sizeof($options) > 0 && !$options['tracking']) {
                                            $options['tracking'] = 1;
                                            $data[$table][$i]['options'] = serialize($options);
                                        }
                                    } elseif(in_array('survey_ID', array_keys($data[$table][$i]))) {                       //Replace deprecated fields with new field names
                                        $data[$table][$i]['surveys_ID'] = $data[$table][$i]['survey_ID'];
                                        unset($data[$table][$i]['survey_ID']);
                                    } elseif($table == 'surveys' && in_array('lesson_ID', array_keys($data[$table][$i]))) {//Replace deprecated fields with new field names
                                        $data[$table][$i]['lessons_ID'] = $data[$table][$i]['lesson_ID'];
                                        unset($data[$table][$i]['lesson_ID']);
                                    } elseif ($table == 'scorm_data' && in_array('exit', array_keys($data[$table][$i]))) {
                                        $data[$table][$i]['scorm_exit'] = $data[$table][$i]['exit'];
                                        unset($data[$table][$i]['exit']);
                                    } elseif ($table == 'f_personal_messages') {
                                        $data[$table][$i]['viewed'] == 'yes' ? $data[$table][$i]['viewed'] = 1 : '';
                                        $data[$table][$i]['viewed'] == 'no'  ? $data[$table][$i]['viewed'] = 0 : '';
                                    } elseif ($table == 'languages') {
                                        !isset($data[$table][$i]['translation']) ? $data[$table][$i]['translation'] = ucfirst($data[$table][$i]['name']) : '';
                                    } elseif ($table == 'courses') {														//Convert old 3.1.x courses to new format
                                    	if ($data[$table][$i]['directions_ID'] == 0) {										//Assign a random direction to courses not having one 
                                    		$data[$table][$i]['directions_ID'] = $data['directions'][0]['id'];
                                    	}
                                    	if ($lessons = unserialize($data[$table][$i]['lessons'])) {
                                    		foreach ($lessons as $lesson) {
                                    			$data['lessons_to_courses'][] = array('courses_ID' => $data[$table][$i]['id'], 'lessons_ID' => $lesson);
                                    		}
                                    	}
                                    	unset($data[$table][$i]['lessons']);                                    	
                                    } elseif ($table == 'content') {												//Update content so that absolute paths become relative
                                    	$patterns 	  = array('/\/view_file.php/',
                                    						  '/\/content\/lessons\//');
                                    	$replacements = array('view_file.php',
                                    						  'content/lessons');
                                    	$data[$table][$i]['data'] = preg_replace($patterns, $replacements, $data[$table][$i]['data'], $limit, $count);

                                        if (!isset($data[$table][$i]['options'])) {
                                            if ($data[$table][$i]['ctg_type'] == 'scorm' || $data[$table][$i]['ctg_type'] == 'scorm_test') {
                                                $data[$table][$i]['options'] = serialize(array('hide_complete_unit' => 1));
                                            } else {
                                                $data[$table][$i]['options'] = '';
                                            }
                                        }
                                    } elseif ($table == 'users_to_lessons') {
                                    	if (isset($temp[$data[$table][$i]['users_LOGIN']]) && $data[$table][$i]['user_type'] == '') {		//If the users_to_lessons does not have user_type information, add the default user_type
                                    		$data[$table][$i]['user_type'] = $temp[$data[$table][$i]['users_LOGIN']];
                                    	}
//
                                    	if (isset($usersToLessons[$data[$table][$i]['users_LOGIN']]) && $usersToLessons[$data[$table][$i]['users_LOGIN']] == $data[$table][$i]['lessons_ID']) {
                                    	    unset($data[$table][$i]);
                                    	    $changeArrayIndices = true;
                                    	} else {
                                    	    $usersToLessons[$data[$table][$i]['users_LOGIN']] = $data[$table][$i]['lessons_ID'];
                                    	}
                                    } elseif ($table == 'files') {
                                        if (isset($data[$table][$i]['original_name'])) {
                                            //pr($data[$table][$i]);debug();
                                            //rename($file['file'], dirname($file['file']).'/'.EfrontFile :: encode(basename($file['original_name'])));
                                            if ($data[$table][$i]['type'] == 'directory') {
                                                unset($data[$table][$i]);
                                            } else {
                                                require_once($path.'tree.class.php');
                                                require_once($path.'filesystem3.class.php');
                                                $newName = str_replace(G_ROOTPATH, '', dirname($data[$table][$i]['file']).'/'.EfrontFile :: encode($data[$table][$i]['original_name']));
                                                $newName = preg_replace("#(.*)www/content/lessons/#", "www/content/lessons/", $newName);
                                                $data[$table][$i]['path'] = $newName;
                                                if ($data[$table][$i]['original_name'] != basename($data[$table][$i]['file'])) {
                                                    if (!is_file(G_ROOTPATH.$newName)) {
                                                        rename($data[$table][$i]['file'], G_ROOTPATH.$newName);
                                                    } else {
                                                        unlink($data[$table][$i]['file']);
                                                    }                                                    
                                                }
                                                unset($data[$table][$i]['file']);
                                                unset($data[$table][$i]['directory']);
                                                unset($data[$table][$i]['original_name']);
                                                unset($data[$table][$i]['physical_name']);
                                                unset($data[$table][$i]['type']);
                                            }
                                        }
                                    } elseif ($table == 'module_hcd_employee_has_skill') {
                                        //3.1.x branch did not have author_login column; add appropriate
                                        if (!isset($data[$table][$i]['author_login'])) {
                                            if (!isset($admin)) {
                                                $count = 0;
                                                while (isset($data['users'][$count]) && $data['users'][$count]['user_type'] != 'administrator') {
                                                    $count++;
                                                }
                                                if (isset($data['users'][$count])) {
                                                    $admin = $data['users'][$count]['login'];
                                                } else {
                                                    $admin = '';
                                                }
                                            }
                                            $data[$table][$i]['author_login'] = $admin;
                                        }
                                    } elseif ($table == 'module_hcd_employees') {
                                        //Replace old 3.1.4 (incompatible) NULL values with zeros
                                        if ($data[$table][$i]['candidate'] == '') {
                                            $data[$table][$i]['candidate'] = 0;
                                        }
                                    } elseif ($table == 'module_hcd_job_description') {
                                        //Replace old 3.1.4 (incompatible) NULL values with the default '1'
                                        if ($data[$table][$i]['employees_needed'] == '') {
                                            $data[$table][$i]['employees_needed'] = 1;
                                        }
                                    } elseif ($table == 'module_hcd_skills') {
                                        //Add absent categories_ID and module_hcd_skill_categories table if needed
                                        if (!isset($data[$table][$i]['categories_ID'])) {
                                            $data[$table][$i]['categories_ID'] = 1;
                                            $data['module_hcd_skill_categories'][0] = array(1, 'Default Category');
                                        }
                                    }

                                    $obsolete_fields = array_diff(array_keys($data[$table][$i]), $table_fields);            //Remove missing fields (usually deprecated fields no longer existing in current version)
                                    foreach ($obsolete_fields as $value) {
                                        unset($data[$table][$i][$value]);
                                    }
                                    
                                    if (isset($data[$table][$i])) {
                                        foreach ($data[$table][$i] as $key => $value) {
                                            $data[$table][$i][$key] = addslashes($value);                  //There is a chance that quotes ' are present into the content. we must escape them in order to avoid database errors. We used to have array_walk here, but it caused memory overuse
                                        }                              
                                    }      
                                    //$rows[$i] = "('".implode("','", $data[$table][$i])."')";
                                }
                                if (sizeof($data[$table]) > 0) {
                                    $data[$table] = array_values($data[$table]);            //Reindex array, in case some values where removed
                                }

                                eF_insertTableDataMultiple($table, $data[$table]);

/*                                
                                sizeof($data[$table]) > 0 ? $keys = implode(",", array_keys($data[$table][0])) : $keys = array();
                                if (sizeof($keys) > 0) {
                                    if (strlen(implode(", ", $rows)) > G_MAXIMUMQUERYSIZE) {                                //In case a query is very large, insert data row by row (See max_allowed_packet in mysql configuration options - defaults to 1M)
                                        for ($j = 0; $j < sizeof($rows); $j++) {
                                            //eF_insertTableData($table, $data[$table][$j]);
                                        }
                                    } else {
                                        try {
                                            //$db -> Execute("insert into $table ($keys) values ".implode(", ", $rows));
                                        } catch (Exception $e) {
                                            $failed_insertions[$table] = "Problem inserting data into table &quot;$table&quot;: ".$e -> msg;
                                        }
                                    }
                                }
*/
                            }
                        }

                        for ($i = 0; $i < sizeof($data['user_profile']); $i++) {
                            $data['user_profile'][$i]['mandatory']     ? $mandatory = "NOT NULL"                                 : $mandatory = "NULL";
                            $data['user_profile'][$i]['default_value'] ? $default   = $data['user_profile'][$i]['default_value'] : $default   = false;
                            try {
                                $db -> Execute("ALTER TABLE users ADD ".$data['user_profile'][$i]['name']." varchar(255) ".$mandatory." DEFAULT '".$default."'");
                            } catch (Exception $e) {
                                $failed_updates[] = $e -> msg;
                            }
                        }

                        if (isset($failed_updates)) {
                            $message      .= implode(', ', $failed_updates)."<br/>";
                            $message_type = 'failure';
                            $errors       = true;
                        }
                        try {                                                                                   //Insert configuration values that are absent from previous versions of efront
                            eF_updateTableData("configuration", array("value" => 1), "value='yes'");            //Convert values from 'yes' and 'no' to 1 and 0
                            eF_updateTableData("configuration", array("value" => 0), "value='no'");
                        } catch (Exception $e) {
                            $message      .= $e -> msg."<br/>";
                            $message_type = 'failure';
                            $errors       = true;
                        }

                        if (version_compare($version_num, 3) == -1) {
                            eF_deleteTableData("configuration", "name='email'");                                    //Delete configuration values that are no longer needed
                            eF_deleteTableData("configuration", "name='hacking_alert'");
                            eF_deleteTableData("configuration", "name='logo_type'");
                            eF_deleteTableData("configuration", "name='colors'");
                            eF_deleteTableData("f_configuration", "name='messages_per_page'");
                            eF_deleteTableData("f_configuration", "name='personal_messages_per_page'");
                            eF_deleteTableData("f_configuration", "name='topics_per_page'");
                        }

                        /**Include filesystem functions*/
                        require_once($path."filesystem.php");

                        if (isset($_GET['migrate'])) {
                            $source_path = $values['dir'];
                            $target_path = $values['new_dir'];
                            //copy_directories is of the form 'source dir' => 'target dir'. This way, we are able to perform a rename of a specific directory
                            $copy_directories = array('/www/content/'         => '/www/content/',
                                                      '/www/Digital Library/' => '/www/Digital Library/',
                                                      '/www/css/custom_css/'  => '/www/css/custom_css/',
                                                      '/www/images/avatars/'  => '/www/images/avatars/',
                                                      '/backups/'             => '/backups/',
                                                      '/upload/'              => '/upload/');

                            foreach ($copy_directories as $src_dir => $target_dir) {
                                if (is_dir($source_path.$src_dir) && is_dir($target_path.$target_dir)) {
                                    $dir_contents = scandir($source_path.$src_dir);
                                    foreach ($dir_contents as $value) {
                                        if (is_dir($source_path.$src_dir.$value) && $value != '.' && $value != '..' && $value != '.svn') {
                                            $failures = eF_copyFolder($source_path.$src_dir.$value, $target_path.$target_dir);
                                            if (is_array($failures)) {
                                                $file_errors[] = implode("<br>", $failures);
                                            }
                                        } elseif (is_file($source_path.$src_dir.$value)) {
                                            copy ($source_path.$src_dir.$value, $target_path.$target_dir.$value);
                                        }
                                    }
                                }
                            }
                            if (isset($file_errors)) {
                                $message      .= implode(", ",$file_errors)."<br/>";
                                $message_type = 'failure';
                                $errors       = true;
                            }
                        } else {
                            $source_path = $path;
                            $target_path = $path;
                        }

                        if (is_dir($source_path.'../message_attachments/')) {                                              //Update old folder 'message_attachments' to 'upload', creating the new structure

                            $dir_contents = eF_getDirContents($source_path.'../message_attachments/', false, false, false);
                            foreach ($dir_contents as $entry) {
    echo "<script>advanceProgress(1)</script>";
    ob_flush();
    flush();
                                if (is_file($source_path.'../message_attachments/'.$entry)) {
                                    copy ($source_path.'../message_attachments/'.$entry, $target_path.'../upload/'.$entry);
                                } elseif (!is_dir($target_path.'../upload/'.$entry)) {
                                    if (mkdir($target_path.'../upload/'.$entry)) {
                                        eF_copyFolder($source_path.'../message_attachments/'.$entry, $target_path.'../upload/'.$entry.'/');
                                        if (!rename($target_path.'../upload/'.$entry.'/'.$entry, $target_path.'../upload/'.$entry.'/message_attachments')) {
                                            $message     .= 'The folder message_attachments/'.$entry.' could not be upgraded. Please copy manually its contents to upload/'.$entry.'/message_attachments<br/>';
                                            $message_type = 'failure';
                                            $errors       = true;
                                        }
                                    } else {
                                        $message     .= 'The folder '.$path.'../upload/'.$entry.' could not be created<br/>';
                                        $message_type = 'failure';
                                        $errors       = true;
                                    }
                                }
                            }

                            if (!$errors) {                             //Rename message_attachements folder, so it does not bother us again...
                                rename($source_path.'../message_attachments/', $source_path.'../message_attachments_old/');
                            }
                        }

                        if ($must_update_files) {                                                   //Convert specific old files to new format
                            $project_files = eF_getTableDataFlat("users_to_projects", "*");
                            foreach ($project_files['filename'] as $key => $file) {
                                if (is_file(G_ROOTPATH.'upload/'.$project_files['users_LOGIN'][$key].'/projects/'.$file)) {
                                    $fields = array('path'          => G_ROOTPATH.'upload/'.$project_files['users_LOGIN'][$key].'/projects/'.$file,
                                                    'users_LOGIN'   => $project_files['users_LOGIN'][$key],
                                                    'timestamp'     => $project_files['upload_timestamp'][$key],
                                                    'description'   => $file);
                                    $file_id = eF_insertTableData("files", $fields);
                                    eF_updateTableData("users_to_projects", array('filename' => $file_id), "users_LOGIN = '".$project_files['users_LOGIN'][$key]."' && projects_ID=".$project_files['projects_ID'][$key]);
                                }
                            }

                            $done_tests = eF_getTableDataFlat("users_to_done_tests", "*");
                            foreach ($done_tests['tests_ID'] as $key => $test_id) {
                                if (is_dir(G_ROOTPATH.'upload/'.$done_tests['users_LOGIN'][$key].'/tests/'.$test_id)) {
                                    $files = EfrontFileSystem :: getContentsFS(G_ROOTPATH.'upload/'.$done_tests['users_LOGIN'][$key].'/tests/'.$test_id);
                                    foreach ($files as $file) {
                                        $fields = array('path'          => $file,
                                                        'users_LOGIN'   => $done_tests['users_LOGIN'][$key],
                                                        'timestamp'     => time(),
                                                        'description'   => basename($file));
                                        $file_id = eF_insertTableData("files", $fields);
                                    }
                                }
                            }

                            $message_attachments = eF_getTableDataFlat("f_personal_messages", "*");
                            foreach ($message_attachments['attachments'] as $key => $attachments) {
                                $attachments = unserialize($attachments);
                                foreach ($attachments as $file) {
                                    if (is_file($file)) {
                                        $fields = array('path'          => $file,
                                                        'users_LOGIN'   => $message_attachments['users_LOGIN'][$key],
                                                        'timestamp'     => time(),
                                                        'description'   => basename($file));
                                        $file_id = eF_insertTableData("files", $fields);
                                    }
                                }
                            }

                        }

    echo "<script>advanceProgress(100)</script>";
    ob_flush();
    flush();

                        if (!isset($errors) || !$errors) {
                            $file_contents = file_get_contents($path.'configuration_temp.php');                            //Load existing configuration file
                            $new_file_contents = preg_replace('/\/\/(require_once\("globals\.php"\);)/', '$1', $file_contents);    //Replace sample settings with current settings
                            file_put_contents($path.'configuration_temp.php', $new_file_contents);

                        } else {
                            $smarty -> assign('T_ERROR', true);
                            if (!$values['new_db_name']) {                                      //If we are upgrading over the existing database, smarty must know, so that it does not display the options "delete database and try again"
                                $smarty -> assign('UPGRADE_SINGLE_DB', true);
                            }
                        }


                    } catch (Exception $e) {
                        $message      .= $e -> msg."<br/>";
                        $message_type = 'failure';
                        $errors       = true;
                    }

                    if (isset($failed_insertions)) {
                        $message      .= implode(', ', $failed_insertions)."<br/>";
                        $message_type = 'failure';
                        $errors       = true;
                    }

                    if ($errors) {
                         $smarty -> assign('T_ERROR', true);
                        if (!$values['new_db_name']) {                                      //If we are upgrading over the existing database, smarty must know, so that it does not display the options "delete database and try again"
                            $smarty -> assign('UPGRADE_SINGLE_DB', true);
                        }
                    } else {
                        echo "<script>document.location='".$_SERVER['PHP_SELF']."?finish=1".$upgrade.$migrate."'</script>";
                    }
                } elseif (isset($values['step2_submit'])) {
                    $file_contents     = file_get_contents($path.'configuration_temp.php');                            //Load existing configuration file
                    $new_file_contents = preg_replace('/\/\/(require_once\("globals\.php"\);)/', '$1', $file_contents);    //Replace sample settings with current settings
                    file_put_contents($path.'configuration_temp.php', $new_file_contents);

                    echo "<script>document.location='".$_SERVER['PHP_SELF']."?finish=1".$upgrade.$migrate."'</script>";
                }
            }
        }

    } else {
        $form -> addElement('select', 'db_type', null, array('mysql' => 'MySQL'));
        $form -> addRule('db_type', 'The database type is mandatory', 'required', null, 'client');                //The database type can only be string and is mandatory
        $form -> addRule('db_type', 'Invalid database type', 'checkParameter', 'string');                //The database type can only be string and is mandatory
		$form -> setDefaults(array('db_type' => 'mysql'));
        $form -> freeze(array('db_type'));																 //Freeze this element, since it can't change for now
        
        $form -> addElement('text', 'db_host', null, 'class = "inputText"');
        $form -> addRule('db_host', 'The database host is mandatory', 'required', null, 'client');                //The database type can only be string and is mandatory
        $form -> addRule('db_host', 'Invalid database host', 'checkParameter', 'alnum_general');         //The database host can only be string and is mandatory

        $form -> addElement('text', 'db_user', null, 'class = "inputText"');
        $form -> addRule('db_user', 'The database user is mandatory', 'required', null, 'client');                //The database type can only be string and is mandatory
        $form -> addRule('db_user', 'Invalid database user', 'checkParameter', 'alnum_general');                //The database user can only be string

        $form -> addElement('password', 'db_password', null, 'class = "inputText"');

        $form -> addElement('text', 'db_name', null, 'class = "inputText"');
        $form -> addRule('db_name', 'The database name is mandatory', 'required', null, 'client');                //The database type can only be string and is mandatory
        $form -> addRule('db_name', 'Invalid database name', 'checkParameter', 'alnum_general');        //The database name can only be string

        $form -> addElement('submit', 'create_tables', 'Create database tables', 'class = "flatButton"');
        $form -> addElement('submit', 'rollback', 'Delete database and retry', 'class = "flatButton"', 'onclick = "return confirm(\'This way all existing data in database will be lost. Are you sure?\')"');
        $form -> addElement('submit', 'step2_submit', 'Continue to next step', 'class = "flatButton"');

        $form -> setDefaults(array('db_host' 	 => 'localhost',
        						   'db_user' 	 => 'root',
        						   'db_password' => '',
        						   'db_name' 	 => 'efront'));
        /*
        Perform the DBMS functions. Below, when we refer to "DBMS" we mean the software (e.g. MySQL)
        and by saying "database" we mean the specific database, e.g. "efront"
        */
        if ($form -> isSubmitted()) {
            if ($form -> validate()) {
                $db = ADONewConnection($form -> exportValue('db_type'));                                    //Set Connection parameter to "mysql"
                $values = $form -> exportValues();

                if (isset($values['create_tables']) || isset($values['rollback'])) {
                    if (isset($values['rollback'])) {
                        try {
                            if ($values['db_name']) {
                                $db -> NConnect($values['db_host'], $values['db_user'], $values['db_password']);
                                $db -> Execute("drop database ".$values['db_name']);
                            }
                        } catch (Exception $e) {
                            $message      = $e->msg;
                            $message_type = 'failure';
                        }
                    }

                    try {
                        $db -> NConnect($values['db_host'], $values['db_user'], $values['db_password']);
                        $db -> Execute("SET NAMES 'UTF8'");
                        $db -> Execute("create database ".$values['db_name']." DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci");                          //Create the new database
                    } catch (Exception $e) {}

                    try {
                        $db -> NConnect($values['db_host'], $values['db_user'], $values['db_password'], $values['db_name']);
                        $db -> Execute("SET NAMES 'UTF8'");
                        $file_contents = trim(file_get_contents("sql_".$values['db_type'].".txt"));                                  //Get the sql queries text
                        $file_contents = explode(';',$file_contents);                                       //Form the sql queries, by splitting each CREATE statement
                        if (!end($file_contents)) {
                            array_pop($file_contents);                                                      //Remove last element, if it is an empty array (which is usually the case)
                        }
                        foreach ($file_contents as $query) {                                                //Run queries
                            preg_match('/CREATE TABLE (\w+) .*/', $query, $matches);
                            try {
                                $db -> Execute($query);
                            } catch (Exception $e) {
                                $failed_tables[] = $e->msg;                                                 //Each failed query will not halt the execution, but will be recorded to this table
                            }
                        }
                        if (isset($failed_tables)) {                                                        //If there were any errors, assign them to smarty to be displayed
                            $smarty -> assign('T_FAILED_TABLES', implode('<br/>', $failed_tables));
                        }
                        if (is_file($path."configuration_temp.php")) {
                            unlink($path."configuration_temp.php");                                         //Delete any temporary configuration file left from previous attempt
                        }
                        $file_contents = file_get_contents('sample_config.php');                            //Load sample configuration file
                        $patterns = array('/(define\("G_DBTYPE", ").*("\);)/',
                                          '/(define\("G_DBHOST", ").*("\);)/',
                                          '/(define\("G_DBUSER", ").*("\);)/',
                                          '/(define\("G_DBPASSWD", ").*("\);)/',
                                          '/(define\("G_DBNAME", ").*("\);)/');
                        $replacements = array('${1}'.$values['db_type'].'${2}', '${1}'.$values['db_host'].'${2}', '${1}'.$values['db_user'].'${2}', '${1}'.$values['db_password'].'${2}', '${1}'.$values['db_name'].'${2}');
                        $new_file_contents = preg_replace($patterns, $replacements, $file_contents, -1, $count);    //Replace sample settings with current settings
                        file_put_contents($path.'configuration_temp.php', $new_file_contents);

                        if (isset($failed_tables)) {                                                        //If there were any errors, assign them to smarty to be displayed
                            $smarty -> assign('T_ERROR', true);
                            $message      = implode(', ', $failed_tables);
                            $message_type = 'failure';
                        } else {
                            header("location:".$_SERVER['PHP_SELF']."?step=3");
                        }
                    } catch (Exception $e) {
                        $message      = $e->msg;
                        $message_type = 'failure';
                    }
                } elseif (isset($values['step2_submit'])) {
                    header("location:".$_SERVER['PHP_SELF']."?step=3");
                }
            }
        }
    }

    $renderer =& new HTML_QuickForm_Renderer_ArraySmarty($smarty);

    $renderer->setRequiredTemplate(
       '{$html}{if $required}
            &nbsp;<span class = "formRequired">*</span>
        {/if}'
        );

    $form -> setJsWarnings('The following errors occured:', 'Please correct the above errors');
    $form -> setRequiredNote('* Denotes mandatory fields');
    $form -> accept($renderer);

    $smarty -> assign('T_DATABASE_FORM', $renderer -> toArray());


}
/*
The third step is used to create administrator account, and to insert default values to database
These values are configuration values, as well as sample accounts and lessons. Furthermore,
the administrator may import users and lessons
*/
else if (isset($_GET['step']) && $_GET['step'] == 3) {
    $_GET['bypass_language'] = 'english';                                       //This is used to make sure the script will continue working, even if the configuration file is not formed as it should
    /**Include the newly created configuration file*/
    require_once($path."configuration_temp.php");
    /**Include the database functions*/
    require_once($path."database.php");
    $db -> Execute("SET NAMES 'UTF8'");

    $form = new HTML_QuickForm("step3_form", "post", $_SERVER['PHP_SELF']."?step=3".$migrate, "", null, true);
    $form -> registerRule('checkParameter', 'callback', 'eF_checkParameter');                   //Register this rule for checking user input with our function, eF_checkParameter

    //Core server settings
    $form -> addElement('select', 'conf[default_language]', null, array('english' => 'english', 'greek' => 'greek'), 'class = "inputSelect"');
    $form -> addElement('text',   'server_name',      null, 'class = "inputText"');
    $form -> addElement('text',   'server_port',      null, 'class = "inputText"');
    $form -> addElement('text',   'root_path',        null, 'class = "inputText"');
    $form -> addElement('advcheckbox', 'conf[caching]', null, null, null, array(0,1));
    $form -> addElement('text', 'conf[cache_timeout]',null, 'class = "inputText"');

    $form -> addRule('server_name', 'The server name is mandatory', 'required', null, 'client');
    $form -> addRule('server_port', 'The server port is mandatory', 'required', null, 'client');
    $form -> addRule('root_path',   'The root path is mandatory',   'required', null, 'client');
    $form -> addRule('conf[server_port]', 'The server port must be numeric', 'numeric', null, 'client');
    $form -> addRule('conf[cache_timeout]', 'The cache timeout must be numeric', 'numeric', null, 'client');


    //Additional server settings
    $form -> addElement('advcheckbox', 'conf[activation]', null, null, null, array(0,1));
    $form -> addElement('advcheckbox', 'conf[onelanguage]', null, null, null, array(0,1));
    $form -> addElement('advcheckbox', 'conf[signup]', null, null, null, array(0,1));
    $form -> addElement('advcheckbox', 'conf[show_footer]', null, null, null, array(0,1));
    $form -> addElement('text',     'conf[ip_white_list]',   null, 'class = "inputText"');
    $form -> addElement('text',     'conf[ip_black_list]',   null, 'class = "inputText"');
    $form -> addElement('text',     'conf[file_white_list]', null, 'class = "inputText"');
    $form -> addElement('text',     'conf[file_black_list]', null, 'class = "inputText"');
    $form -> addElement('text',     'conf[max_file_size]',   null, 'class = "inputText"');
    //Mail server settings
    $form -> addElement('text',     'conf[smtp_host]', null, 'class = "inputText"');
    $form -> addElement('text',     'conf[smtp_user]', null, 'class = "inputText"');
    $form -> addElement('password', 'conf[smtp_pass]', null, 'class = "inputText"');
    $form -> addElement('text',     'conf[smtp_port]', null, 'class = "inputText"');
    $form -> addElement('advcheckbox', 'conf[smtp_auth]', null, null, null, array(0,1));
    //LDAP server settings
    $form -> addElement('advcheckbox', 'conf[activate_ldap]', null, null, 'class = "inputCheckBox" onclick = "eF_js_activateElements(\'ldap\')"', array(0,1));
    $form -> addElement('advcheckbox', 'conf[only_ldap]',     null, null, 'class = "inputCheckBox" readonly = "readonly" style = "color:#808080"', array(0,1));
    $form -> addElement('text',     'conf[ldap_server]',   null, 'class = "inputText" readonly = "readonly" style = "color:#808080"');
    $form -> addElement('text',     'conf[ldap_port]',     null, 'class = "inputText" readonly = "readonly"  style = "color:#808080"');
    $form -> addRule('conf[ldap_port]', 'The server port must be numeric', 'numeric', null, 'client');
    $form -> addElement('text',     'conf[ldap_base_dn]',  null, 'class = "inputText" readonly = "readonly"  style = "color:#808080"');
    $form -> addElement('text',     'conf[ldap_bind_dn]',  null, 'class = "inputText" readonly = "readonly"  style = "color:#808080"');
    $form -> addElement('password', 'conf[ldap_password]', null, 'class = "inputText" readonly = "readonly"  style = "color:#808080"');
    $form -> addElement('text',     'conf[ldap_protocol]', null, 'class = "inputText" readonly = "readonly"  style = "color:#808080"');
    //LDAP attribute mapping
    $form -> addElement('text', 'conf[ldap_preferredlanguage]', null, 'class = "inputText" readonly = "readonly"  style = "color:#808080"');
    $form -> addElement('text', 'conf[ldap_telephonenumber]',   null, 'class = "inputText" readonly = "readonly"  style = "color:#808080"');
    $form -> addElement('text', 'conf[ldap_mail]',              null, 'class = "inputText" readonly = "readonly"  style = "color:#808080"');
    $form -> addElement('text', 'conf[ldap_postaladdress]',     null, 'class = "inputText" readonly = "readonly"  style = "color:#808080"');
    $form -> addElement('text', 'conf[ldap_l]',                 null, 'class = "inputText" readonly = "readonly"  style = "color:#808080"');
    $form -> addElement('text', 'conf[ldap_cn]',                null, 'class = "inputText" readonly = "readonly"  style = "color:#808080"');
    $form -> addElement('text', 'conf[ldap_uid]',               null, 'class = "inputText" readonly = "readonly"  style = "color:#808080"');

    $form -> addElement('submit', 'step3_submit', 'Continue', 'class = "flatButton"');
    $form -> addElement('submit', 'rollback', 'Rollback', 'class = "flatButton"');
    $form -> addElement('submit', 'continue_anyway', 'Continue anyway', 'class = "flatButton"');

    /**Include configuration class*/
    require_once($path."configuration.class.php");
    
    $form -> setDefaults(array('server_name'   => dirname(dirname('http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'])).'/',               //This cuts out install/install.php from the current path
                               'server_port'   => $_SERVER['SERVER_PORT'],
                               'root_path'     => str_replace('\\','/',dirname(realpath('..'))).'/',
                               'conf[caching]' => '1',
                               'conf[cache_timeout]' => '3600'));
    if ($migrate) {                                                                                     //If we are migrating, we read configuration values from the database
        $form -> setDefaults(EfrontConfiguration :: getValues());
    } else {
        $form -> setDefaults(array('conf' => EfrontConfiguration :: getDefaultValues()));
    }
    if ($form -> isSubmitted()) {
        if ($form -> validate()) {
            $values = $form -> exportValues();                                  //Get all the form values

            if (isset($values['step3_submit'])) {
                foreach ($values['conf'] as $key => $value) {                   //Get all the configuration values
                    try {
                        EfrontConfiguration :: setValue($key, $value);
                    } catch (Exception $e) {
                        $failed_insertions[] = $e -> msg;                       //Catch any error messages, to be shown later
                    }
                }
                try {                                                           //Insert languages to corresponding table
                    if (!$migrate) {                                                                                     //If we are migrating, we read configuration values from the database
                        eF_insertTableData("languages", array('name' => 'greek',   'active' => 1, 'translation' => mb_convert_encoding('ÅëëçíéêÜ', 'UTF-8', 'ISO-8859-7')));
                        eF_insertTableData("languages", array('name' => 'english', 'active' => 1, 'translation' => 'English'));
                    }
                } catch (Exception $e) {
                    $failed_insertions[] = $e -> msg;                           //Catch any error messages, to be shown later
                }
                if (isset($failed_insertions)) {                                //This means we experienced problems
                    $smarty -> assign("T_FAILED_INSERTIONS", implode("<br/>", $failed_insertions));
                } else {
                    $file_contents = file_get_contents($path.'configuration_temp.php');                            //Load configuration file
                    $patterns      = array('/(define\("G_SERVERNAME", ").*("\);)/',
                                           '/(define\("G_SERVERPORT", ").*("\);)/',
                                           '/(define\("G_ROOTPATH", ").*("\);)/',
                                           '/\/\/(require_once\("globals\.php"\);)/');
                    //if ($values['server_port'] != 80) {
                    //    $values['server_name'] = trim($values['server_name'], "/").':'.$values['server_port'];
                    //}
                    $replacements      = array('${1}'.rtrim($values['server_name'], "/")."/".'${2}', '${1}'.$values['server_port'].'${2}', '${1}'.$values['root_path'].'${2}', '${1}');       //${1} and ${2} is needed in port, because port is a number
                    $new_file_contents = preg_replace($patterns, $replacements, $file_contents);    //Replace sample settings with current settings
                    file_put_contents($path.'configuration_temp.php', $new_file_contents);

                    $migrate ? header("location:".$_SERVER['PHP_SELF']."?finish=1") : header("location:".$_SERVER['PHP_SELF']."?step=4");             //Redirect anyway, even if errors occured during the configuration values insertion
                }
            } elseif (isset($values['rollback'])) {                             //If the user asked to rollback, empty the configuration table
                try {
                    $db -> Execute("truncate table configuration");
                    $db -> Execute("truncate table languages");
                    $smarty -> assign("T_ROLLBACK_PROBLEM", false);             //Catch any error messages durng the table truncation
                } catch (Exception $e) {
                    $smarty -> assign("T_ROLLBACK_PROBLEM", $e -> msg);         //Catch any error messages durng the table truncation
                }
            } elseif (isset($values['continue_anyway'])) {
                $file_contents = file_get_contents($path.'configuration_temp.php');                            //Load configuration file
                $patterns = array('/(define\("G_SERVERNAME", ").*("\);)/',
                                  '/(define\("G_SERVERPORT", ").*("\);)/',
                                  '/(define\("G_ROOTPATH", ").*("\);)/',
                                  '/\/\/(require_once\("globals\.php"\);)/');
                $replacements = array('${1}'.rtrim($values['server_name'], "/")."/".'${2}', '${1}'.'80'.'${2}', '${1}'.$values['root_path'].'${2}', '${1}');
                $new_file_contents = preg_replace($patterns, $replacements, $file_contents);    //Replace sample settings with current settings
                file_put_contents($path.'configuration_temp.php', $new_file_contents);

                $migrate ? header("location:".$_SERVER['PHP_SELF']."?finish=1") : header("location:".$_SERVER['PHP_SELF']."?step=4");             //Redirect anyway, even if errors occured during the configuration values insertion
            }
        }
    }

    $renderer =& new HTML_QuickForm_Renderer_ArraySmarty($smarty);

    $renderer->setRequiredTemplate(
       '{$html}{if $required}
            &nbsp;<span class = "formRequired">*</span>
        {/if}'
        );

    $renderer->setErrorTemplate(
       '{$html}{if $error}
            <span class = "formError">{$error}</span>
        {/if}'
        );
    $form -> setJsWarnings('The following errors occured:', 'Please correct the above errors');
    $form -> setRequiredNote('* Denotes mandatory fields');
    $form -> accept($renderer);

    $smarty -> assign('T_DATABASE_FORM', $renderer -> toArray());
}
/*
In this step the user creates Administrator and default user accounts
*/
else if (isset($_GET['step']) && $_GET['step'] == 4) {
    /**Include the newly created configuration file*/
    require_once($path."configuration_temp.php");
    /**Include the database functions*/
    require_once($path."database.php");
    $db -> Execute("SET NAMES 'UTF8'");
    /**Include the configuration class*/
    require_once($path."configuration.class.php");

    $configuration = EfrontConfiguration :: getValues();

    $form = new HTML_QuickForm("step4_form", "post", $_SERVER['PHP_SELF']."?step=4".$upgrade, "", null, true);
    $form -> registerRule('checkParameter', 'callback', 'eF_checkParameter');                   //Register this rule for checking user input with our function, eF_checkParameter

    //Administrator account settings
    $form -> addElement('text', 'admin_user',      null, 'class = "inputText"');
    $form -> addElement('password', 'admin_password',  null, 'class = "inputText"');
    $form -> addElement('password', 'admin_repeat_pwd',null, 'class = "inputText"');
    $form -> addElement('text', 'admin_name',      null, 'class = "inputText"');
    $form -> addElement('text', 'admin_surname',   null, 'class = "inputText"');
    $form -> addElement('text', 'admin_email',     null, 'class = "inputText"');
    $form -> addElement('select', 'admin_language', null, array('english' => 'english', 'greek' => 'greek'), 'class = "inputSelect"');

    $form -> addRule('admin_user',      'The administrator login is mandatory',    'required',       null, 'client');
    $form -> addRule('admin_password',  'The administrator password is mandatory', 'required',       null, 'client');
    $form -> addRule('admin_repeat_pwd','You must repeat password',                'required',       null, 'client');
    $form -> addRule('admin_name',      'The administrator name is mandatory',     'required',       null, 'client');
    $form -> addRule('admin_surname',   'The administrator surname is mandatory',  'required',       null, 'client');
    $form -> addRule('admin_email',     'The administrator email is mandatory',    'required',       null, 'client');
    $form -> addRule('admin_email',     'Invalid administrator email',             'checkParameter', 'email');
    $form -> addRule(array('admin_password', 'admin_repeat_pwd'), 'The passwords do not match', 'compare', null, 'client');

    $form -> setDefaults(array('admin_user' 	=> 'admin', 
    						   'admin_language' => $configuration['default_language']));
	$form -> freeze(array('admin_language'));
	
    //Professor sample account settings
    $form -> addElement('text', 'prof_user',      null, 'class = "inputText"');
    $form -> addElement('text', 'prof_password',  null, 'class = "inputText" onclick = "this.value = \'\';this.type=\'password\'"');
    $form -> addElement('text', 'prof_repeat_pwd',null, 'class = "inputText" onclick = "this.value = \'\';this.type=\'password\'"');
    $form -> addElement('text', 'prof_name',      null, 'class = "inputText"');
    $form -> addElement('text', 'prof_surname',   null, 'class = "inputText"');
    $form -> addElement('text', 'prof_email',     null, 'class = "inputText"');
    $form -> addElement('select', 'prof_language', null, array('english' => 'english', 'greek' => 'greek'), 'class = "inputSelect"');

    $form -> addRule('prof_user',      'The professor login is mandatory',    'required',       null, 'client');
    $form -> addRule('prof_password',  'The professor password is mandatory', 'required',       null, 'client');
    $form -> addRule('prof_repeat_pwd','You must repeat password',            'required',       null, 'client');
    $form -> addRule('prof_name',      'The professor name is mandatory',     'required',       null, 'client');
    $form -> addRule('prof_surname',   'The professor surname is mandatory',  'required',       null, 'client');
    $form -> addRule('prof_email',     'The professor email is mandatory',    'required',       null, 'client');
    $form -> addRule('prof_email',     'Invalid professor email',             'checkParameter', 'email');
    $form -> addRule(array('prof_password', 'prof_repeat_pwd'), 'The passwords do not match', 'compare', null, 'client');

    $form -> setDefaults(array('prof_user'       => 'professor',
                               'prof_password'   => 'professor',
                               'prof_repeat_pwd' => 'professor',
                               'prof_name'       => 'Professor',
                               'prof_surname'    => 'eFront',
                               'prof_email'      => 'professor@example.com',
                               'prof_language'   => $configuration['default_language']));
    $form -> freeze(array('prof_language'));

    //Student sample account settings
    $form -> addElement('text', 'stud_user',      null, 'class = "inputText"');
    $form -> addElement('text', 'stud_password',  null, 'class = "inputText" onclick = "this.value = \'\';this.type=\'password\'"');
    $form -> addElement('text', 'stud_repeat_pwd',null, 'class = "inputText" onclick = "this.value = \'\';this.type=\'password\'"');
    $form -> addElement('text', 'stud_name',      null, 'class = "inputText"');
    $form -> addElement('text', 'stud_surname',   null, 'class = "inputText"');
    $form -> addElement('text', 'stud_email',     null, 'class = "inputText"');
    $form -> addElement('select', 'stud_language', null, array('english' => 'english', 'greek' => 'greek'), 'class = "inputSelect"');

    $form -> addRule('stud_user',      'The student login is mandatory',    'required',       null, 'client');
    $form -> addRule('stud_password',  'The student password is mandatory', 'required',       null, 'client');
    $form -> addRule('stud_repeat_pwd','You must repeat password',          'required',       null, 'client');
    $form -> addRule('stud_name',      'The student name is mandatory',     'required',       null, 'client');
    $form -> addRule('stud_surname',   'The student surname is mandatory',  'required',       null, 'client');
    $form -> addRule('stud_email',     'The student email is mandatory',    'required',       null, 'client');
    $form -> addRule('stud_email',     'Invalid student email',             'checkParameter', 'email');
    $form -> addRule(array('stud_password', 'stud_repeat_pwd'), 'The passwords do not match', 'compare', null, 'client');

    $form -> setDefaults(array('stud_user'       => 'student',
                               'stud_password'   => 'student',
                               'stud_repeat_pwd' => 'student',
                               'stud_name'       => 'Student',
                               'stud_surname'    => 'eFront',
                               'stud_email'      => 'student@example.com',
                               'stud_language'   => $configuration['default_language']));
	$form -> freeze(array('stud_language'));
	
    $form -> addElement('checkbox', 'create_lesson', null, null, 'id = "activate_stud" class = "inputCheckBox"');
    $form -> addElement('checkbox', 'activate_prof', null, null, 'id = "activate_prof" class = "inputCheckBox" onclick = "eF_js_activateElements(\'prof\')"');
    $form -> addElement('checkbox', 'activate_stud', null, null, 'id = "activate_stud" class = "inputCheckBox" onclick = "eF_js_activateElements(\'stud\')"');
    $form -> setDefaults(array('create_lesson' => true,
                               'activate_prof' => true,
                               'activate_stud' => true));

    $form -> addElement('submit', 'step4_submit', 'Continue', 'class = "flatButton"');
    $form -> addElement('submit', 'try_again', 'Try Again', 'class = "flatButton"');
    $form -> addElement('submit', 'continue_anyway', 'Continue anyway', 'class = "flatButton"');

    if ($form -> isSubmitted()) {
        if ($form -> validate()) {
            $values = $form -> exportValues();                                  //Get all the form values
            try {
                if (isset($values['continue_anyway'])) {
                    header("location:".$_SERVER['PHP_SELF']."?finish=1");
                }
                if (isset($values['try_again'])) {
                    $user = EfrontUserFactory :: factory($values['admin_user']);
                    $user -> delete();
                    if (isset($values['activate_prof'])) {
                        $user = EfrontUserFactory :: factory($values['prof_user']);
                        $user -> delete();
                    }
                    if (isset($values['activate_stud'])) {
                        $user = EfrontUserFactory :: factory($values['stud_user']);
                        $user -> delete();
                    }
                }
            } catch (Exception $e) {
                $errors[] = $e -> getMessage();
            }

            $admin_values = array('login'    => $values['admin_user'],
                                  'password' => $values['admin_password'],
                                  'email'    => $values['admin_email'],
                                  'name'     => $values['admin_name'],
                                  'surname'  => $values['admin_surname'],
                                  'languages_NAME' => $values['admin_language'],
                                  'active'   => '1',
                                  'user_type'=> 'administrator');

            try {
                EfrontUser :: createUser($admin_values);
                if (MODULE_HCD_INTERFACE) {                 
                    EfrontHcdUser :: createUser(array("users_login" => $values['admin_user']));
                }
            } catch (Exception $e) {
                $errors[] = 'The administrator account was not created: '.$e -> msg;
            }

            try {
                EfrontConfiguration :: setValue('system_email', $values['admin_email']);
            } catch (Exception $e) {
                $errors[] = 'The system email could not be set: '.$e -> getMessage();
            }

            if (isset($values['activate_prof'])) {
                $smarty -> assign("T_CREATE_PROF", true);
                $prof_values = array('login'    => $values['prof_user'],
                                     'password' => $values['prof_password'],
                                     'email'    => $values['prof_email'],
                                     'name'     => $values['prof_name'],
                                     'surname'  => $values['prof_surname'],
                                     'languages_NAME' => $values['prof_language'],
                                     'active'   => '1',
                                     'user_type'=> 'professor');
                try {
                    EfrontUser :: createUser($prof_values);
                    if (MODULE_HCD_INTERFACE) {
                        EfrontHcdUser :: createUser(array("users_login" => $values['prof_user']));
                    }
                } catch (Exception $e) {
                    $errors[] = 'The professor account was not created: '.$e -> getMessage();
                }

            }

            if (isset($values['activate_stud'])) {
                $smarty -> assign("T_CREATE_STUD", true);
                $stud_values = array('login'    => $values['stud_user'],
                                     'password' => $values['stud_password'],
                                     'email'     => $values['stud_email'],
                                     'name'     => $values['stud_name'],
                                     'surname'  => $values['stud_surname'],
                                     'languages_NAME' => $values['stud_language'],
                                     'active'   => '1',
                                     'user_type'=> 'student');

                try {
                    EfrontUser :: createUser($stud_values);
                    if (MODULE_HCD_INTERFACE) {
                        EfrontHcdUser :: createUser(array("users_login" => $values['stud_user']));
                    }
                } catch (Exception $e) {
                    $errors[] = 'The student account was not created: '.$e -> getMessage();
                }

            }

            if (isset($values['create_lesson'])) {
                $default_lessons = array('Greedy algorithms' => 'Greedy Algorithms.zip', 'Maya civilization' => 'maya_civilization.tar.gz');
                $result          = eF_getTableData("directions", "id", "name='Default direction'");      //Check if the direction was created in a previous attempt
                if (sizeof($result) > 0) {
                    $direction_id = $result[0]['id'];
                } else {
                    $direction_id = eF_insertTableData("directions", array('name' => 'Default direction', 'active' => 1));
                }

                if ($direction_id) {
                    $result = eF_getTableDataFlat("lessons", "id, name");                                 //Check if a lessons were created in a previous attempt
                    if (sizeof($result) > 0) {
                        foreach ($result['id'] as $id) {
                            EfrontLesson::deleteLesson($id);
                        }
                    }
                    $fields = array('directions_ID'  => $direction_id,
                                    'active'         => 1,
                                    'languages_NAME' => $configuration['default_language']);
                    $users = eF_getTableDataFlat("users", "login, user_type", "user_type = 'student' or user_type = 'professor'");
                    foreach ($default_lessons as $name => $filename) {
                        //list($lesson_ids[$name], $message, $message_type) = eF_createLesson(array_merge(array('name' => $name), $fields));
                        try {
                            $file   = new EfrontFile(EfrontDirectory :: normalize(getcwd()).'/'.$filename);
                            $lesson = EfrontLesson :: createLesson(array_merge(array('name' => $name), $fields));
                            $file   = $file -> copy($lesson -> getDirectory());
                            $lesson -> import($file);
                            $lesson -> addUsers($users['login'], $users['user_type']);
                        } catch (Exception $e) {
                            $errors[] = $e -> getMessage();
                        }
                    }
                } else {
                    $smarty -> assign("T_ERROR", "The direction could not be created");
                }

            }
            //Create default forum
            $fields_forum = array('title'       => "General Forum",
                                  'lessons_ID'  => 0,
                                  'parent_id'   => 0,
                                  'status'      => 'public',
                                  'users_LOGIN' => 'admin',
                                  'comments'    => '');
            eF_insertTableData("f_forums", $fields_forum);

            $smarty -> assign("T_CREATE_ERRORS", implode("<br/>", $errors));

            if (!isset($errors)) {
                header("location:".$_SERVER['PHP_SELF']."?finish=1");
            }
        }
    }

    $renderer =& new HTML_QuickForm_Renderer_ArraySmarty($smarty);

    $renderer->setRequiredTemplate(
       '{$html}{if $required}
            &nbsp;<span class = "formRequired">*</span>
        {/if}'
        );

    $renderer->setErrorTemplate(
       '{$html}{if $error}
            <span class = "formError">{$error}</span>
        {/if}'
        );
    $form -> setJsWarnings('The following errors occured:', 'Please correct the above errors');
    $form -> setRequiredNote('* Denotes mandatory fields');
    $form -> accept($renderer);

    $smarty -> assign('T_DATABASE_FORM', $renderer -> toArray());

}

/*
Final step
*/
elseif (isset($_GET['finish'])) {
    if (is_file($path."configuration.php") && is_file($path."configuration_temp.php")) {
        if (unlink ($path."configuration.php")) {
            rename($path."configuration_temp.php", $path."configuration.php");
        } else {
            $smarty -> assign("T_ERROR", 'The existing configuration file could not be replaced with the new one. Please do so manually, renaming the file libraries/configuration_temp.php to libraries/configuration.php');
        }
    } elseif (is_file($path."configuration_temp.php")) {
        rename($path."configuration_temp.php", $path."configuration.php");
    }
    $smarty -> clear_all_cache();
    $smarty -> clear_compiled_tpl();

}

$smarty -> assign("T_SERVERNAME", dirname(dirname('http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'])).'/');
$smarty -> assign("T_MESSAGE", $message);
$smarty -> assign("T_MESSAGE_TYPE", $message_type);
$smarty -> load_filter('output', 'eF_template_formatTimestamp');
if (preg_match("/compatible; MSIE 6/", $_SERVER['HTTP_USER_AGENT']) && !preg_match("/compatible; MSIE 7/", $_SERVER['HTTP_USER_AGENT'])) {
    $smarty -> assign("T_BROWSER", 'IE6');
    $smarty -> load_filter('output', 'eF_template_replacePng');
}


$smarty -> display ("install/install.tpl");


?>

