]> git.mxchange.org Git - mailer.git/blobdiff - inc/install-functions.php
Rewrote some code, added templates/functions:
[mailer.git] / inc / install-functions.php
index 40a6ab62805d0fee38de66b4dacd8cdacfd23365..4222ee2e9570c99cad783211bf9a7addb50a29f3 100644 (file)
@@ -16,7 +16,7 @@
  * $Author::                                                          $ *
  * -------------------------------------------------------------------- *
  * Copyright (c) 2003 - 2009 by Roland Haeder                           *
- * Copyright (c) 2009 - 2012 by Mailer Developer Team                   *
+ * Copyright (c) 2009 - 2013 by Mailer Developer Team                   *
  * For more information visit: http://mxchange.org                      *
  *                                                                      *
  * This program is free software; you can redistribute it and/or modify *
@@ -36,7 +36,7 @@
  ************************************************************************/
 
 // Some security stuff...
-if ((!defined('__SECURITY')) || (!isInstallationPhase())) {
+if ((!defined('__SECURITY')) || (!isInstaller())) {
        die();
 } // END - if
 
@@ -54,7 +54,7 @@ function initInstaller () {
                'mysql_host'      => 'database_config',
                'mysql_dbase'     => 'database_config',
                'mysql_prefix'    => 'database_config',
-               'mysql_type'      => 'database_config',
+               'mysql_engine'    => 'database_config',
                'mysql_login'     => 'database_config',
                'mysql_password1' => 'database_config',
                'mysql_password2' => 'database_config',
@@ -68,48 +68,64 @@ function initInstaller () {
                'warn_no_pass'    => 'other_config',
                'write_footer'    => 'other_config',
                'enable_backlink' => 'other_config',
+               // first_admin
+               'admin_login'     => 'first_admin',
+               'admin_email'     => 'first_admin',
+               'admin_password1' => 'first_admin',
+               'admin_password2' => 'first_admin',
        );
+
+       // Set mininmum password length/score and other config entries
+       setConfigEntry('min_password_length', 5);
+       setConfigEntry('min_password_score' , 3);
+       setConfigEntry('verbose_sql'        , 'N');
 }
 
 // Write the local config-local.php file from "template"
-function doInstallWriteLocalConfigurationFile ($path) {
+function doInstallWriteLocalConfigurationFile ($path, $url, $title, $slogan, $email, $noPassword, $writeFooter, $backLink, $databaseHost, $databaseName, $databaseLogin, $databasePassword, $databasePrefix, $databaseType, $smtpHost, $smtpUser, $smtpPassword) {
        // Copy the config template and verify it
-       copyFileVerified(postRequestElement('spath') . 'inc/config-local.php.dist', postRequestElement('spath') . getCachePath() . 'config-local.php', 0644);
-
-       // Ok, all done. So we can write the config data to the php files
-       // Do only write these if they differ from auto-detected values
-       if (postRequestElement('spath') != getPath()) changeDataInLocalConfigurationFile('SERVER-PATH', "setConfigEntry('PATH', '", "');", postRequestElement('spath'), 0);
-       if (postRequestElement('burl')  != getUrl())  changeDataInLocalConfigurationFile('HOST-URL', "setConfigEntry('URL', '", "');", postRequestElement('burl'), 0);
+       copyFileVerified($path . 'inc/config-local.php.dist', $path . getCachePath() . 'config-local.php', 0644);
+
+       /*
+        * Ok, all done. So we can write the config data to the php files. Do only
+        * write these if they differ from auto-detected values.
+        */
+       if ($path != getPath()) {
+               changeDataInLocalConfigurationFile('SERVER-PATH', "setConfigEntry('PATH', '", "');", $path, 0);
+       } // END - if
+       if ($url != getUrl()) {
+               changeDataInLocalConfigurationFile('HOST-URL', "setConfigEntry('URL', '", "');", $url, 0);
+       } // END - if
 
        // Write more data
-       changeDataInLocalConfigurationFile('MAIN-TITLE', "setConfigEntry('MAIN_TITLE', '", "');", postRequestElement('title'), 0);
-       changeDataInLocalConfigurationFile('SLOGAN', "setConfigEntry('SLOGAN', '", "');", postRequestElement('slogan'), 0);
-       changeDataInLocalConfigurationFile('WEBMASTER', "setConfigEntry('WEBMASTER', '", "');", postRequestElement('email'), 0);
-       changeDataInLocalConfigurationFile('NULLPASS-WARNING', "setConfigEntry('WARN_NO_PASS', '", "');", postRequestElement('warn_no_pass'), 0);
-       changeDataInLocalConfigurationFile('WRITE-FOOTER', "setConfigEntry('WRITE_FOOTER', '", "');", postRequestElement('wfooter'), 0);
-       changeDataInLocalConfigurationFile('BACKLINK', "setConfigEntry('ENABLE_BACKLINK', '", "');", postRequestElement('blink'), 0);
+       changeDataInLocalConfigurationFile('MAIN-TITLE', "setConfigEntry('MAIN_TITLE', '", "');", $title, 0);
+       changeDataInLocalConfigurationFile('SLOGAN', "setConfigEntry('SLOGAN', '", "');", $slogan, 0);
+       changeDataInLocalConfigurationFile('WEBMASTER', "setConfigEntry('WEBMASTER', '", "');", $email, 0);
+       changeDataInLocalConfigurationFile('NULLPASS-WARNING', "setConfigEntry('WARN_NO_PASS', '", "');", $noPassword, 0);
+       changeDataInLocalConfigurationFile('WRITE-FOOTER', "setConfigEntry('WRITE_FOOTER', '", "');", $writeFooter, 0);
+       changeDataInLocalConfigurationFile('BACKLINK', "setConfigEntry('ENABLE_BACKLINK', '", "');", $backLink, 0);
        // @TODO DEACTIVATED: changeDataInLocalConfigurationFile('OUTPUT-MODE', "setConfigEntry('OUTPUT_MODE', '", "');", postRequestElement('omode'), 0);
-       changeDataInLocalConfigurationFile('MYSQL-HOST', "      'host'     => '", "',", postRequestElement('mysql','host'), 0);
-       changeDataInLocalConfigurationFile('MYSQL-DBASE', "     'dbase'    => '", "',", postRequestElement('mysql','dbase'), 0);
-       changeDataInLocalConfigurationFile('MYSQL-LOGIN', "     'login'    => '", "',", postRequestElement('mysql','login'), 0);
-       changeDataInLocalConfigurationFile('MYSQL-PASSWORD', "  'password' => '", "',", postRequestElement('mysql','pass1'), 0);
-       changeDataInLocalConfigurationFile('MYSQL-PREFIX', "setConfigEntry('_MYSQL_PREFIX', '", "');", postRequestElement('mysql','prefix'), 0);
-       changeDataInLocalConfigurationFile('TABLE-TYPE', "setConfigEntry('_TABLE_TYPE', '", "');", postRequestElement('mysql','type'), 0);
-       changeDataInLocalConfigurationFile('SMTP-HOSTNAME', "setConfigEntry('SMTP_HOSTNAME', '", "');", postRequestElement('smtp_host'), 0);
-       changeDataInLocalConfigurationFile('SMTP-USER', "setConfigEntry('SMTP_USER', '", "');", postRequestElement('smtp_user'), 0);
-       changeDataInLocalConfigurationFile('SMTP-PASSWORD', "setConfigEntry('SMTP_PASSWORD', '", "');", postRequestElement('smtp_pass1'), 0);
+       changeDataInLocalConfigurationFile('MYSQL-HOST', "      'host'     => '", "',", $databaseHost, 0);
+       changeDataInLocalConfigurationFile('MYSQL-DBASE', "     'dbase'    => '", "',", $databaseName, 0);
+       changeDataInLocalConfigurationFile('MYSQL-LOGIN', "     'login'    => '", "',", $databaseLogin, 0);
+       changeDataInLocalConfigurationFile('MYSQL-PASSWORD', "  'password' => '", "',", $databasePassword, 0);
+       changeDataInLocalConfigurationFile('MYSQL-PREFIX', "setConfigEntry('_MYSQL_PREFIX', '", "');", $databasePrefix, 0);
+       changeDataInLocalConfigurationFile('TABLE-TYPE', "setConfigEntry('_TABLE_TYPE', '", "');", $databaseType, 0);
+       changeDataInLocalConfigurationFile('SMTP-HOSTNAME', "setConfigEntry('SMTP_HOSTNAME', '", "');", $smtpHost, 0);
+       changeDataInLocalConfigurationFile('SMTP-USER', "setConfigEntry('SMTP_USER', '", "');", $smtpUser, 0);
+       changeDataInLocalConfigurationFile('SMTP-PASSWORD', "setConfigEntry('SMTP_PASSWORD', '", "');", $smtpPassword, 0);
 
        // Generate a long site-key and write it
        changeDataInLocalConfigurationFile('SITE-KEY', "setConfigEntry('SITE_KEY', '", "');", generatePassword(50), 0);
 
        // Script is now installed
-       changeDataInLocalConfigurationFile('INSTALLED', "setConfigEntry('MXCHANGE_INSTALLED', '", "');", 'Y', 0);
+       return changeDataInLocalConfigurationFile('INSTALLED', "setConfigEntry('MAILER_INSTALLED', '", "');", 'Y', 0);
 }
 
 // Adds a given template with content to install output stream
 function addTemplateToInstallContent ($template, $content = array()) {
        // Load the template
-       $out = loadTemplate($template, true, $content);
+       $out = loadTemplate($template, TRUE, $content);
 
        // Add it to output
        addToInstallContent($out);
@@ -135,7 +151,7 @@ function getInstallerContent () {
                $content = $GLOBALS['install_content'];
        } else {
                // Nothing found, this needs fixing
-               $content = displayMessage('{--INSTALLER_CONTENT_404--}', true);
+               $content = returnMessage('{--INSTALLER_CONTENT_404--}');
        }
 
        // Return content
@@ -149,7 +165,7 @@ function readSqlDump ($FQFN) {
 
        // Remove some unwanted chars
        $content = str_replace(chr(13), '', $content);
-       $content = str_replace("\n\n", chr(10), $content);
+       $content = str_replace(PHP_EOL . PHP_EOL, PHP_EOL, $content);
 
        // Return the content
        return $content;
@@ -158,7 +174,7 @@ function readSqlDump ($FQFN) {
 // Generates the installer menu by simply loading another template
 function generateInstallerMenu () {
        // Load installer menu template
-       $OUT = loadTemplate('install_menu', true);
+       $OUT = loadTemplate('install_menu', TRUE);
 
        // Return loaded content
        return $OUT;
@@ -167,7 +183,7 @@ function generateInstallerMenu () {
 // Generate the install footer navigation by simply loading another template
 function generateInstallerFooterNavigation () {
        // Load installer menu template
-       $OUT = loadTemplate('install_footer', true);
+       $OUT = loadTemplate('install_footer', TRUE);
 
        // Return loaded content
        return $OUT;
@@ -179,7 +195,7 @@ function generateInstallerDatabaseTypeOptions () {
                '/ARRAY/',
                array('MyISAM', 'InnoDB'),
                array('{--INSTALLER_TABLE_TYPE_MYISAM--}', '{--INSTALLER_TABLE_TYPE_INNODB--}'),
-               getSession('mysql_type')
+               getSession('mysql_engine')
        );
 }
 
@@ -211,6 +227,26 @@ function isPlainInstaller () {
        return $isPlainInstaller;
 }
 
+// Handle all given failed fields
+function handleInstallerFailedFields ($failedFields) {
+       // Don't do anything with no array or no entries
+       if (!isFilledArray($failedFields)) {
+               // Abort here
+               reportBug(__FUNCTION__, __LINE__, 'failedFields[]=' . gettype($failedFields) . ' verification failed');
+       } // END - if
+
+       // Handle all
+       $out = '<ol>';
+       foreach ($failedFields as $key => $field) {
+               // "Translate" it
+               $out .= '<li>{--INSTALLER_FIELD_FAILED_' . strtoupper($field) . '--}</li>';
+       } // END - foreach
+       $out .= '</ol>';
+
+       // Return it
+       return $out;
+}
+
 // Checks given key/value pair if it is valid by a call-back
 function isInstallerDataValid (&$saveStatus, $key, $value) {
        //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'key=' . $key . ',value=' . $value . ' - ENTERED!');
@@ -223,7 +259,7 @@ function isInstallerDataValid (&$saveStatus, $key, $value) {
                //* NOISY-DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'Call-back function ' . $callbackName . ' not found. saveStatus[status]=' . $saveStatus['status'] . ', key=' . $key . ', value=' . $value);
 
                // All fine (CAREFULL!)
-               return true;
+               return TRUE;
        } // END - if
 
        // Then call it back
@@ -231,7 +267,7 @@ function isInstallerDataValid (&$saveStatus, $key, $value) {
 
        // Is it not valid?
        //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'key=' . $key . ',value=' . $value . ',isValid=' . intval($isValid));
-       if ($isValid === false) {
+       if ($isValid === FALSE) {
                // Then add it to saveStatus
                array_push($saveStatus['failed_fields'], $key);
        } // END - if
@@ -252,10 +288,10 @@ function doInstallerPostCheck ($currentTab, &$saveStatus) {
        // Is the function there?
        if (!function_exists($callbackName)) {
                // Not found, which is not bad, but it means the post-check won't be run
-               //* NOISY-DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'Call-back function ' . $callbackName . ' not found. saveStatus[status]=' . $saveStatus['status'] . ', currentTab=' . $currentTab);
+               /* NOISY-DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'Call-back function ' . $callbackName . ' not found. saveStatus[status]=' . $saveStatus['status'] . ', currentTab=' . $currentTab);
 
                // Abort here
-               return;
+               return FALSE;
        } // END - if
 
        // Init 'tab-specific error message'
@@ -269,13 +305,13 @@ function doInstallerPostCheck ($currentTab, &$saveStatus) {
        $isValid = (bool) call_user_func($callbackName, $currentTab);
 
        // Is it not valid?
-       if (($isValid === false) || (count($GLOBALS['installer_failed_fields'][$currentTab]) > 0)) {
+       if (($isValid === FALSE) || (isFilledArray($GLOBALS['installer_failed_fields'][$currentTab]))) {
                // Then change status and message
                $saveStatus['status']  = 'failed';
                $saveStatus['message'] = '{%message,INSTALLER_POST_CHECK_' . strtoupper($currentTab) . '_FAILED=' . $GLOBALS['installer_post_error'][$currentTab] . '%}';
 
-               // Do we have failed fields?
-               if (count($GLOBALS['installer_failed_fields'][$currentTab]) > 0) {
+               // Is there failed fields?
+               if (isFilledArray($GLOBALS['installer_failed_fields'][$currentTab])) {
                        // Then merge both
                        $saveStatus['failed_fields'] = merge_array($saveStatus['failed_fields'], $GLOBALS['installer_failed_fields'][$currentTab]);
                } // END - if
@@ -309,6 +345,50 @@ function addKeyValueToInstallerOverviewGroup ($key, $value) {
        $GLOBALS['installer_overview'][$group][$key] = $value;
 }
 
+//-----------------------------------------------------------------------------
+//                        Template call-back functions
+//-----------------------------------------------------------------------------
+
+// ----------------- Extensions -----------------
+
+// Generates (and returns) a table from all extensions
+function generateInstallerExtensionTable () {
+       // Generate extension list
+       $extensions = loadAllExtensionsByTemplate();
+
+       // "Walk" through all
+       $OUT = '';
+       foreach ($extensions as $extension) {
+               // Remove prefix + suffix
+               $ext_name = substr(basename($extension), 4, -4);
+
+               // Is the extension not in development and not admintheme* ?
+               if ((loadExtension($ext_name, 'test', '0.0.0', TRUE)) && (isExtensionProductive($ext_name)) && (substr($ext_name, 0, 10) != 'admintheme')) {
+                       // Default is not disabled
+                       $disabled = '';
+                       if (in_array($ext_name, array('sql_patches', 'timezone'))) {
+                               // Always keep this enabled
+                               $disabled = ' disabled="disabled"';
+                       } // END - if
+
+                       // Initialize content array
+                       $content = array(
+                               'ext_name'    => $ext_name,
+                               'ext_version' => getExtensionVersion($ext_name),
+                               'checked'     => getExtensionSelectedFromSession($ext_name, 'extensions'),
+                               'disabled'    => $disabled,
+                               'description' => loadTemplate('ext_' . $ext_name, TRUE),
+                       );
+
+                       // Load row template
+                       $OUT .= loadTemplate('install_list_extensions_row', TRUE, $content);
+               } // END - if
+       } // END - foreach
+
+       // Load main template
+       return loadTemplate('install_list_extensions', TRUE, $OUT);
+}
+
 //-----------------------------------------------------------------------------
 //                   Call-back functions to check validity
 //-----------------------------------------------------------------------------
@@ -322,6 +402,9 @@ function isInstallerBasePathValid ($value) {
        $isValid = (
                // Is it a directory?
                (isDirectory($value))
+       &&
+               // Doesn't contain dots
+               (strpos($value, '..') === FALSE)
        &&
                // Is there a trailing slash?
                (substr($value, -1, 1) == '/')
@@ -331,6 +414,9 @@ function isInstallerBasePathValid ($value) {
        &&
                // What about gen_sql_patches.php?
                (isFileReadable($value . 'inc/gen_sql_patches.php'))
+       &&
+               // And how about referral-functions.php?
+               (isFileReadable($value . 'inc/referral-functions.php'))
        );
 
        // Return it
@@ -364,17 +450,41 @@ function isInstallerBaseUrlValid ($value) {
        return $isValid;
 }
 
+// Call-back function to checl validity of 'main_title'
+function isInstallerMainTitleValid ($value) {
+       // Is it valid?
+       // @TODO Comparing with DEFAULT_MAIN_TITLE doesn't work
+       $isValid = ((strlen($value) >= 4) && ($value != getMessage('DEFAULT_MAIN_TITLE')));
+
+       // Return it
+       return $isValid;
+}
+
+// Call-back function to checl validity of 'slogan'
+function isInstallerSloganValid ($value) {
+       // Is it valid?
+       $isValid = ((strlen($value) >= 4) && ($value != getMessage('DEFAULT_SLOGAN')));
+
+       // Return it
+       return $isValid;
+}
+
 // Call-back function to check validity of 'webmaster'
 function isInstallerWebmasterValid ($value) {
        //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'value=' . $value . ' - ENTERED!');
        // Is it a valid email address?
-       $isValid = (
+       $isValid = ((
                // Is it a valid email address?
                (isEmailValid($value))
        ||
-               // Or do we have 'localhost/127.0.0.1' as hostname? Then don't check email address (e.g. you@localhost)
-               (in_array(detectServerName(), array('localhost', '127.0.0.1')))
-       );
+               // Or is there 'localhost/127.0.0.1' as hostname? Then don't check email address (e.g. you@localhost)
+               (isDeveloperSystem())
+       ) && (
+               // Is not default "email address"
+               $value != getMessage('DEFAULT_WEBMASTER')
+       ) && (
+               strlen($value) >= 11
+       ));
 
        // Return it
        //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'value=' . $value . ',isValid=' . intval($isValid) . ' - EXIT');
@@ -387,6 +497,8 @@ function isInstallerWebmasterValid ($value) {
 function isInstallerMysqlHostValid ($value) {
        // This value must match a hostname or IP address
        $isValid = (
+               // Shall not be empty
+               (!empty($value)) && (
                // Is localhost/127.0.0.1? (mostly the case)
                (in_array($value, array('localhost', '127.0.0.1')))
        ||
@@ -395,14 +507,14 @@ function isInstallerMysqlHostValid ($value) {
        ||
                // Host name match
                (preg_match('/([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,6}/', $value))
-       );
+       ));
 
        // Return it
        return $isValid;
 }
 
-// Call-back function to check validity of 'mysql_type'
-function isInstallerMysqlTypeValid ($value) {
+// Call-back function to check validity of 'mysql_engine'
+function isInstallerMysqlEngineValid ($value) {
        // This value must be 'MyISAM' or 'InnoDB'
        $isValid = in_array($value, array('MyISAM', 'InnoDB'));
 
@@ -410,19 +522,153 @@ function isInstallerMysqlTypeValid ($value) {
        return $isValid;
 }
 
+// Call-back function to check validity of 'mysql_dbase'
+function isInstallerMysqlDbaseValid ($value) {
+       // This value must not be empty
+       $isValid = ((!empty($value)) && ($value != 'your_database'));
+
+       // Return it
+       return $isValid;
+}
+
+// Call-back function to check validity of 'mysql_login'
+function isInstallerMysqlLoginValid ($value) {
+       // This value must not be empty
+       $isValid = ((!empty($value)) && ($value != 'your_login'));
+
+       // Return it
+       return $isValid;
+}
+
+// Call-back function to check validity of 'mysql_prefix'
+function isInstallerMysqlPrefixValid ($value) {
+       // This value must not be empty
+       $isValid = !empty($value);
+
+       // Return it
+       return $isValid;
+}
+
 // ----------------- SMTP configuration -----------------
 
 // ----------------- Other configuration -----------------
 
+// ----------------- First administator -----------------
+
+// Call-back function to check validity of 'admin_login'
+function isInstallerAdminLoginValid ($value) {
+       // Length should not be shorter than 4 characters
+       return (strlen($value) >= 4);
+}
+
+// Call-back function to check validity of 'admin_email'
+function isInstallerAdminEmailValid ($value) {
+       // Just call webmaster-check function
+       return isInstallerWebmasterValid($value);
+}
+
+// Call-back function to check validity of 'admin_password1'
+function isInstallerAdminPassword1Valid ($value) {
+       // Check if it is strong
+       return isStrongPassword($value);
+}
+
+// Call-back function to check validity of 'admin_password2'
+function isInstallerAdminPassword2Valid ($value) {
+       // Check if it is strong
+       return isStrongPassword($value);
+}
+
+// ----------------- Extensions -----------------
+
+// Call-back function to check 'sel' (array!)
+function isInstallerSelValid ($value) {
+       // $value is not an array, is really bad.
+       if (!is_array($value)) {
+               // Is no array
+               reportBug(__FUNCTION__, __LINE__, 'sel,value[]=' . gettype($value) . '!=array');
+       } // END - if
+
+       // Add always missing ext-sql_patches
+       $value['sql_patches'] = '1';
+
+       // Default is fine
+       $isValid = TRUE;
+
+       // "Walk" through all extensions
+       foreach ($value as $ext_name => $sel) {
+               // Is this extension choosen?
+               if ($sel != '1') {
+                       // Skip this
+                       continue;
+               } // END - if
+
+               // Can it be loaded?
+               $isValid = (($isValid) && (loadExtension($ext_name, 'test', '0.0.0', TRUE)));
+       } // END - foreach
+
+       // Remove 'sel' from POST data as it cannot be saved
+       unsetPostRequestElement('sel');
+
+       // Save it in session (sorry to do that here :( )
+       setSession('extensions', implode(':', array_keys($value)));
+
+       // Return result
+       return $isValid;
+}
+
 //-----------------------------------------------------------------------------
 //                 Call-back functions to post-check validity
 //-----------------------------------------------------------------------------
 
+// Call-back function to check if base data is valid
+function isInstallerPostBaseDataValid ($currentTab) {
+       // By default it is not valid
+       $isValid = FALSE;
+
+       // Is the base path valid?
+       if (!isInstallerBasePathValid(postRequestElement('base_path'))) {
+               // Then mark it
+               $GLOBALS['installer_post_error'][$currentTab] = '{--INSTALLER_POST_BASE_PATH_INVALID--}';
+               array_push($GLOBALS['installer_failed_fields'][$currentTab], 'base_path');
+               return FALSE;
+       } elseif (!isInstallerBaseUrlValid(postRequestElement('base_url'))) {
+               // Then mark it
+               $GLOBALS['installer_post_error'][$currentTab] = '{--INSTALLER_POST_BASE_URL_INVALID--}';
+               array_push($GLOBALS['installer_failed_fields'][$currentTab], 'base_url');
+               return FALSE;
+       } elseif (strlen(postRequestElement('main_title')) < 3) {
+               // To short
+               $GLOBALS['installer_post_error'][$currentTab] = '{--INSTALLER_POST_MAIN_TITLE_INVALID--}';
+               array_push($GLOBALS['installer_failed_fields'][$currentTab], 'main_title');
+               return FALSE;
+       } elseif (strlen(postRequestElement('slogan')) < 3) {
+               // To short
+               $GLOBALS['installer_post_error'][$currentTab] = '{--INSTALLER_POST_SLOGAN_INVALID--}';
+               array_push($GLOBALS['installer_failed_fields'][$currentTab], 'slogan');
+               return FALSE;
+       } elseif (!isInstallerWebmasterValid(postRequestElement('webmaster'))) {
+               // Then mark it
+               $GLOBALS['installer_post_error'][$currentTab] = '{--INSTALLER_POST_WEBMASTER_INVALID--}';
+               array_push($GLOBALS['installer_failed_fields'][$currentTab], 'webmaster');
+               return FALSE;
+       } else {
+               // All fine
+               $isValid = TRUE;
+
+               // Remember this tab in session
+               installTabOkay($currentTab);
+       }
+
+       // Return it
+       return $isValid;
+}
+
 // Call-back function to check if database configuration in POST is valid
 function isInstallerPostDatabaseConfigValid ($currentTab) {
        // By default nothing is valid
-       $isValid       = false;
-       $engineValid   = false;
+       $isValid       = FALSE;
+       $engineValid   = FALSE;
        $missingTables = 0;
 
        // Do both passwords match?
@@ -430,135 +676,134 @@ function isInstallerPostDatabaseConfigValid ($currentTab) {
                // Password 1 not set
                $GLOBALS['installer_post_error'][$currentTab] = '{--INSTALLER_POST_DATABASE_PASSWORD1_EMPTY--}';
                array_push($GLOBALS['installer_failed_fields'][$currentTab], 'mysql_password1');
-               return false;
+               return FALSE;
        } elseif ((isPostRequestElementSet('mysql_password1')) && (!isPostRequestElementSet('mysql_password2'))) {
                // Password 2 not set
                $GLOBALS['installer_post_error'][$currentTab] = '{--INSTALLER_POST_DATABASE_PASSWORD2_EMPTY--}';
                array_push($GLOBALS['installer_failed_fields'][$currentTab], 'mysql_password2');
-               return false;
+               return FALSE;
        } elseif (postRequestElement('mysql_password1') != postRequestElement('mysql_password2')) {
                // Passwords mismatch
                $GLOBALS['installer_post_error'][$currentTab] = '{--INSTALLER_POST_DATABASE_PASSWORDS_MISMATCH--}';
                array_push($GLOBALS['installer_failed_fields'][$currentTab], 'mysql_password1', 'mysql_password2');
-               return false;
+               return FALSE;
        } // END - if
 
-       // Restore PHP's own error handler
-       if (!restore_error_handler()) {
-               // This is fatal
-               reportBug(__FUNCTION__, __LINE__, 'Could not unregister error handler.');
-       } // END - if
+       // Remove any previous flag
+       unsetSqlLinkUp(__FUNCTION__, __LINE__);
 
        // Try to connect to the database
-       $linkResource = SQL_CONNECT(postRequestElement('mysql_host'), postRequestElement('mysql_login'), postRequestElement('mysql_password1'), __FUNCTION__, __LINE__);
+       sqlConnectToDatabase(postRequestElement('mysql_host'), postRequestElement('mysql_login'), postRequestElement('mysql_password1'), __FUNCTION__, __LINE__);
 
        // Is the link up
-       if (!is_resource($linkResource)) {
-               // Restore own error handler again
-               set_error_handler('__errorHandler');
-
+       if (!isSqlLinkUp()) {
                // Cannot connect to database
                $GLOBALS['installer_post_error'][$currentTab] = '{--INSTALLER_POST_DATABASE_CONNECT_ERROR--}';
                array_push($GLOBALS['installer_failed_fields'][$currentTab], 'mysql_login', 'mysql_password1', 'mysql_password2');
-               return false;
+               return FALSE;
        } // END - if
 
        // Then attempt to select the database
-       if (!SQL_SELECT_DB(postRequestElement('mysql_dbase'), __FUNCTION__, __LINE__)) {
-               // Restore own error handler again
-               set_error_handler('__errorHandler');
-
+       if (!sqlSelectDatabase(postRequestElement('mysql_dbase'), __FUNCTION__, __LINE__)) {
                // Could not find database
                $GLOBALS['installer_post_error'][$currentTab] = '{--INSTALLER_POST_DATABASE_SELECT_FAILED--}';
                array_push($GLOBALS['installer_failed_fields'][$currentTab], 'mysql_dbase');
-               return false;
+
+               // Disconnect here, we don't need idle database connections laying around
+               sqlCloseLink(__FUNCTION__, __LINE__);
+
+               // Abort here
+               return FALSE;
        } // END - if
 
        // Set database name and prefix
        setConfigEntry('__DB_NAME'    , postRequestElement('mysql_dbase'));
        setConfigEntry('_MYSQL_PREFIX', postRequestElement('mysql_prefix'));
 
-       // Restore own error handler again
-       set_error_handler('__errorHandler');
-
        // Get an array of all supported engines
-       $engines = getArrayFromSupportedSqlEngines();
+       $engines = getArrayFromSupportedSqlEngines(postRequestElement('mysql_engine'));
 
        // Is this an array?
        if (!is_array($engines)) {
-               // Restore own error handler again
-               set_error_handler('__errorHandler');
-
                // Something bad happened
                $GLOBALS['installer_post_error'][$currentTab] = '{--INSTALLER_POST_DATABASE_ENGINES_SQL_ERROR--}';
-               array_push($GLOBALS['installer_failed_fields'][$currentTab], 'mysql_type');
-               return false;
-       } elseif (count($engines) == 0) {
-               // Restore own error handler again
-               set_error_handler('__errorHandler');
+               array_push($GLOBALS['installer_failed_fields'][$currentTab], 'mysql_engine');
 
+               // Disconnect here, we don't need idle database connections laying around
+               sqlCloseLink(__FUNCTION__, __LINE__);
+
+               // Abort here
+               return FALSE;
+       } elseif (!isFilledArray($engines)) {
                // No engine is active
                $GLOBALS['installer_post_error'][$currentTab] = '{--INSTALLER_POST_DATABASE_NO_ENGINES_ACTIVE--}';
-               array_push($GLOBALS['installer_failed_fields'][$currentTab], 'mysql_type');
-               return false;
+               array_push($GLOBALS['installer_failed_fields'][$currentTab], 'mysql_engine');
+
+               // Disconnect here, we don't need idle database connections laying around
+               sqlCloseLink(__FUNCTION__, __LINE__);
+
+               // Abort here
+               return FALSE;
        }
 
        // Then check all, if the requested is working
        foreach ($engines as $engineArray) {
                // By default the selected engine is not valid
-               $engineValid = false;
+               $engineValid = FALSE;
 
                // Is the engine there?
-               if (strtolower($engineArray['Engine']) == strtolower(postRequestElement('mysql_type'))) {
+               if (strtolower($engineArray['Engine']) == strtolower(postRequestElement('mysql_engine'))) {
                        // Okay, engine is found
-                       $engineValid = true;
+                       $engineValid = TRUE;
                        break;
                } // END - if
        } // END - foreach
 
        // So, is the engine found?
-       if ($engineValid === false) {
-               // Restore own error handler again
-               set_error_handler('__errorHandler');
-
+       if ($engineValid === FALSE) {
                // Requested engine is not active
                $GLOBALS['installer_post_error'][$currentTab] = '{--INSTALLER_POST_DATABASE_ENGINE_UNSUPPORTED--}';
-               array_push($GLOBALS['installer_failed_fields'][$currentTab], 'mysql_type');
-               return false;
+               array_push($GLOBALS['installer_failed_fields'][$currentTab], 'mysql_engine');
+
+               // Disconnect here, we don't need idle database connections laying around
+               sqlCloseLink(__FUNCTION__, __LINE__);
+
+               // Abort here
+               return FALSE;
        } // END - if
 
        // Init some known tables
        $tables = array(
                // Admins
-               'admins'      => true,
+               'admins'      => TRUE,
                // Admin menu
-               'admin_menu'  => true,
+               'admin_menu'  => TRUE,
                // Categories
-               'cats'        => true,
+               'cats'        => TRUE,
                // Configuration
-               'config'      => true,
+               'config'      => TRUE,
                // Extensions
-               'extensions'  => true,
+               'extensions'  => TRUE,
                // Guest menu
-               'guest_menu'  => true,
+               'guest_menu'  => TRUE,
                // Max receive
-               'max_receive' => true,
+               'max_receive' => TRUE,
                // Member menu
-               'member_menu' => true,
+               'member_menu' => TRUE,
                // Module registry
-               'mod_reg'     => true,
+               'mod_reg'     => TRUE,
                // Payments
-               'payments'    => true,
+               'payments'    => TRUE,
                // Sending pool
-               'pool'        => true,
+               'pool'        => TRUE,
                // Referral banner
-               'refbanner'   => true,
+               'refbanner'   => TRUE,
                // Referral levels
-               'refdepths'   => true,
+               'refdepths'   => TRUE,
                // Referral system
-               'refsystem'   => true,
+               'refsystem'   => TRUE,
                // Task system
-               'task_system' => true,
+               'task_system' => TRUE,
        );
 
        // So check if all tables are not there
@@ -567,7 +812,7 @@ function isInstallerPostDatabaseConfigValid ($currentTab) {
                $tables[$tableName] = ifSqlTableExists($tableName);
 
                // Is it (hopefully not) there?
-               if ($tables[$tableName] === false) {
+               if ($tables[$tableName] === FALSE) {
                        // This does not exist
                        $missingTables++;
                } // END - if
@@ -577,22 +822,100 @@ function isInstallerPostDatabaseConfigValid ($currentTab) {
        $isValid = (count($tables) == $missingTables);
 
        // Disconnect here, we don't need idle database connections laying around
-       SQL_CLOSE(__FUNCTION__, __LINE__);
-
-       // Restore own error handler again
-       set_error_handler('__errorHandler');
+       sqlCloseLink(__FUNCTION__, __LINE__);
 
        // If the status is true, disconnect the database
-       if ($isValid === false) {
+       if ($isValid === FALSE) {
                // Still something bad happened (e.g. tables found)
                $GLOBALS['installer_post_error'][$currentTab] = '{--INSTALLER_POST_DATABASE_IN_USE--}';
                array_push($GLOBALS['installer_failed_fields'][$currentTab], 'mysql_dbase');
-       } // END - if
+       } else {
+               // Remember this tab in session
+               installTabOkay($currentTab);
+       }
 
        // Return status
        return $isValid;
 }
 
+// Call-back function to check if first admin data is valid
+function isInstallerPostFirstAdminValid ($currentTab) {
+       // Is all data valid?
+       if (!isPostRequestElementSet('admin_login')) {
+               // Login not set
+               $GLOBALS['installer_post_error'][$currentTab] = '{--INSTALLER_POST_FIRST_ADMIN_LOGIN_EMPTY--}';
+               array_push($GLOBALS['installer_failed_fields'][$currentTab], 'admin_login');
+               return FALSE;
+       } elseif (strlen(postRequestElement('admin_login')) < 4) {
+               // Login to short
+               $GLOBALS['installer_post_error'][$currentTab] = '{--INSTALLER_POST_FIRST_ADMIN_LOGIN_SHORT--}';
+               array_push($GLOBALS['installer_failed_fields'][$currentTab], 'admin_login');
+               return FALSE;
+       } elseif (!isPostRequestElementSet('admin_email')) {
+               // Email address not set
+               $GLOBALS['installer_post_error'][$currentTab] = '{--INSTALLER_POST_FIRST_ADMIN_EMAIL_EMPTY--}';
+               array_push($GLOBALS['installer_failed_fields'][$currentTab], 'admin_email');
+               return FALSE;
+       } elseif (!isInstallerAdminEmailValid(postRequestElement('admin_email'))) {
+               // Invalid email address
+               $GLOBALS['installer_post_error'][$currentTab] = '{--INSTALLER_POST_FIRST_ADMIN_EMAIL_INVALID--}';
+               array_push($GLOBALS['installer_failed_fields'][$currentTab], 'admin_email');
+               return FALSE;
+       } elseif ((!isPostRequestElementSet('admin_password1')) && (isPostRequestElementSet('admin_password2'))) {
+               // Password 1 not set
+               $GLOBALS['installer_post_error'][$currentTab] = '{--INSTALLER_POST_FIRST_ADMIN_PASSWORD1_EMPTY--}';
+               array_push($GLOBALS['installer_failed_fields'][$currentTab], 'admin_password1');
+               return FALSE;
+       } elseif ((isPostRequestElementSet('admin_password1')) && (!isPostRequestElementSet('admin_password2'))) {
+               // Password 2 not set
+               $GLOBALS['installer_post_error'][$currentTab] = '{--INSTALLER_POST_FIRST_ADMIN_PASSWORD2_EMPTY--}';
+               array_push($GLOBALS['installer_failed_fields'][$currentTab], 'admin_password2');
+               return FALSE;
+       } elseif (postRequestElement('admin_password1') != postRequestElement('admin_password2')) {
+               // Passwords mismatch
+               $GLOBALS['installer_post_error'][$currentTab] = '{--INSTALLER_POST_FIRST_ADMIN_PASSWORDS_MISMATCH--}';
+               array_push($GLOBALS['installer_failed_fields'][$currentTab], 'admin_password1', 'admin_password2');
+               return FALSE;
+       } elseif (!isStrongPassword(postRequestElement('admin_password1'))) {
+               // Weak passwords entered
+               $GLOBALS['installer_post_error'][$currentTab] = '{--INSTALLER_POST_FIRST_ADMIN_PASSWORDS_WEAK--}';
+               array_push($GLOBALS['installer_failed_fields'][$currentTab], 'admin_password1', 'admin_password2');
+               return FALSE;
+       } // END - if
+
+       // All tests passed
+       return TRUE;
+}
+
+// Store given tab in session
+function installTabOkay ($currentTab) {
+       // Is it set?
+       if (isSessionVariableSet('installer_okay')) {
+               // Is this tab already found?
+               if (strpos(getSession('installer_okay'), $currentTab) === FALSE) {
+                       // Then extend it
+                       setSession('installer_okay', getSession('installer_okay') . ';' . $currentTab);
+               } // END - if
+       } else {
+               // Initially set it
+               setSession('installer_okay', $currentTab);
+       }
+}
+
+// Checks whether at least the required tabs are completed
+function isInstallationDataCompleted () {
+       // Check both
+       $isCompleted = (
+               (isSessionVariableSet('installer_okay')) &&
+               (strpos(getSession('installer_okay'), 'base_data') !== FALSE) &&
+               (strpos(getSession('installer_okay'), 'database_config') !== FALSE)
+       );
+
+       // Return it
+       //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'isCompleted=' . intval($isCompleted) . ',installer_okay=' . getSession('installer_okay'));
+       return $isCompleted;
+}
+
 // Call-back function to check if enable_backlink is Y/N
 function isInstallerEnableBacklinkValid ($currentTab) {
        // Check and return it
@@ -617,5 +940,17 @@ function isInstallerOutputModeValid ($currentTab) {
        return in_array($currentTab, array('render', 'direct'));
 }
 
+// Wrapper to import given installation SQL dump
+function importInstallSqlDump ($dumpName) {
+       // Import the file
+       importSqlDump('install', $dumpName, 'install');
+}
+
+// Wrapper to check if tables.sql and menu-foo.sql are readable
+function isInstallerSqlsReadable ($path) {
+       // Determine it
+       return ((isFileReadable($path . 'install/tables.sql')) && (isFileReadable($path . 'install/menu-' . getLanguage() . '.sql')));
+}
+
 // [EOF]
 ?>