]> git.mxchange.org Git - mailer.git/blobdiff - inc/ajax/ajax_installer.php
Mailer project rwritten:
[mailer.git] / inc / ajax / ajax_installer.php
index f9c50322d0119c20a4853349607cd17a7843d056..f1e7eb7aaa5d0f55b8119a98cac4fd560e08a8cd 100644 (file)
  ************************************************************************/
 
 // Some security stuff...
-if (!defined('__SECURITY')) {
-       die();
+if ((!defined('__SECURITY')) || (!isAjaxOutputMode()) || (!isInstallationPhase())) {
+       header('HTTP/1.1 403 Forbidden');
+       die(json_encode(array('reply_content' => 'Access forbidden'), JSON_FORCE_OBJECT));
 } // END - if
 
+//-----------------------------------------------------------------------------
+//         Generic call-back functions, they all rely on session data
+//-----------------------------------------------------------------------------
+
+// Establish a database link
+function establishAjaxInstallerDatabaseLink () {
+       // This requires some session data
+       if (!isSessionDataSet(array('mysql_host', 'mysql_dbase', 'mysql_prefix', 'mysql_login', 'mysql_password1', 'mysql_password2', 'mysql_engine'))) {
+               // Some required session data is not set
+               reportBug(__FUNCTION__, __LINE__, 'Required session data for this step not found.');
+       } // END - if
+
+       // Remove any previous flag
+       unsetSqlLinkUp(__FUNCTION__, __LINE__);
+
+       // Establish link
+       $linkResource = SQL_CONNECT(getSession('mysql_host'), getSession('mysql_login'), getSession('mysql_password1'), __FUNCTION__, __LINE__);
+
+       // Is this a link resource?
+       if (!is_resource($linkResource)) {
+               // Is not a resource
+               reportBug(__FUNCTION__, __LINE__, 'linkResource[]=' . gettype($linkResource) . ', expected: link resource');
+       } // END - if
+
+       // Does selecting the database work?
+       if (!SQL_SELECT_DB(getSession('mysql_dbase'), __FUNCTION__, __LINE__)) {
+               // Could not be selected
+               reportBug(__FUNCTION__, __LINE__, 'Could not select database ' . getSession('mysql_dbase'));
+       } elseif ((!isFileReadable(getSession('base_path') . 'install/tables.sql')) || (!isFileReadable(getSession('base_path') . 'install/menu-'.getLanguage().'.sql'))) {
+               // Installation area not found
+               reportBug(__FUNCTION__, __LINE__, 'SQL dumps not found. Please extract ALL files from the archive or checkout all files out from SVN.');
+       } elseif (ifFatalErrorsDetected()) {
+               // Some other fatal error occured
+               reportBug(__FUNCTION__, __LINE__, 'Some fatal error detected, please check debug.log for details.');
+       } // END - if
+
+       // Set type, prefix from POST data and database name for later queries
+       setConfigEntry('_TABLE_TYPE'  , getSession('mysql_engine'));
+       setConfigEntry('_MYSQL_PREFIX', getSession('mysql_prefix'));
+       setConfigEntry('__DB_NAME'    , getSession('mysql_dbase'));
+}
+
 //-----------------------------------------------------------------------------
 //             Call-back functions for processing AJAX requests
 //-----------------------------------------------------------------------------
@@ -56,7 +99,7 @@ function doAjaxProcessInstall () {
        } // END - if
 
        // Notify all modules that we are installing
-       $GLOBALS['__mailer_installing'] =  true;
+       $GLOBALS['__mailer_installing'] = TRUE;
 
        // Again we do a call-back, so generate a function name depending on 'do'
        $callbackName = 'doAjaxInstaller' . capitalizeUnderscoreString(postRequestElement('do'));
@@ -77,7 +120,7 @@ function doAjaxProcessInstall () {
 // Processes installer request for testing
 function doAjaxInstallerTest () {
        // Load the "test passed" template
-       setAjaxReplyContent(loadTemplate('ajax_test_passed', true));
+       setAjaxReplyContent(loadTemplate('ajax_test_passed', TRUE));
 
        // All okay if we reach this point
        setHttpStatus('200 OK');
@@ -100,6 +143,7 @@ function doAjaxInstallerFooterNavigation () {
                case 'database_config':
                case 'smtp_config':
                case 'other_config':
+               case 'extensions':
                        array_push($enabledNavigations, 'previous');
                case 'welcome': // Only 'next' works for welcome page
                        array_push($enabledNavigations, 'next');
@@ -107,6 +151,10 @@ function doAjaxInstallerFooterNavigation () {
 
                case 'overview': // Enable only 'previous'
                        array_push($enabledNavigations, 'previous');
+                       if (isInstallationDataCompleted()) {
+                               // Add 'finish'
+                               array_push($enabledNavigations, 'finish');
+                       } // END - if
                        break;
 
                default: // Unsupported value
@@ -118,7 +166,34 @@ function doAjaxInstallerFooterNavigation () {
        } // END - switch
 
        // Output the array for JSON reply
-       setAjaxReplyContent(json_encode($enabledNavigations, JSON_FORCE_OBJECT));
+       setAjaxReplyContent(encodeJson($enabledNavigations));
+
+       // All okay if we reach this point
+       setHttpStatus('200 OK');
+}
+
+// Processes installer AJAX calls for content-requests
+function doAjaxInstallerDoStep () {
+       // 'step' must be there
+       if (!isPostRequestElementSet('step')) {
+               // This shall not happen
+               reportBug(__FUNCTION__, __LINE__, 'The JavaScript did not send "step" which is fatal.');
+       } // END - if
+
+       // Construct call-back name
+       $callbackName = 'doAjaxInstallerStep' . capitalizeUnderscoreString(postRequestElement('step'));
+
+       // Is the function there?
+       if (function_exists($callbackName)) {
+               // Call it for setting values in session
+               call_user_func($callbackName);
+       } else {
+               // Log missing functions
+               reportBug(__FUNCTION__, __LINE__, 'Call-back function ' . $callbackName . ' does not exist.');
+       }
+
+       // Set dummy content
+       setAjaxReplyContent(encodeJson(postRequestElement('step').'=OK'));
 
        // All okay if we reach this point
        setHttpStatus('200 OK');
@@ -141,13 +216,13 @@ function doAjaxInstallerRequestContent () {
                call_user_func($callbackName);
        } else {
                // Log missing functions
-               logDebugMessage(__FUNCTION__, __LINE__, 'Call-back function ' . $callbackName . ' does not exist.');
+               reportBug(__FUNCTION__, __LINE__, 'Call-back function ' . $callbackName . ' does not exist.');
        }
 
        // Is the HTTP status still the same? (204 No Content)
        if (getHttpStatus() == '204 No Content') {
                // We use the current access level 'install' as prefix and construct a template name
-               setAjaxReplyContent(loadTemplate('install_page_' . trim(postRequestElement('tab')), true));
+               setAjaxReplyContent(loadTemplate('install_page_' . trim(postRequestElement('tab')), TRUE));
 
                // Has the template been loaded?
                if (isset($GLOBALS['template_content']['html']['install_page_' . trim(postRequestElement('tab'))])) {
@@ -155,7 +230,7 @@ function doAjaxInstallerRequestContent () {
                        setHttpStatus('200 OK');
                } else {
                        // Set 404 error
-                       setHttpStatus('404 NOT FOUND');
+                       setHttpStatus('404 Not Found');
                }
        } // END - if
 }
@@ -171,8 +246,14 @@ function doAjaxInstallerChangeWarning () {
        // "Walk" through all elements
        $OUT = '<ol>';
        foreach (explode(':', postRequestElement('elements')) as $element) {
-               // Add row
-               $OUT .= '<li>{--INSTALLER_CHANGED_ELEMENT_' . strtoupper($element) . '--}</li>';
+               // Is it an extension?
+               if (substr($element, 0, 4) == 'ext_') {
+                       // Add row for extension
+                       $OUT .= '<li>{%message,INSTALLER_CHANGED_ELEMENT_EXTENSION=' . str_replace('_', '-', $element) . '%}</li>';
+               } else {
+                       // Add generic row
+                       $OUT .= '<li>{--INSTALLER_CHANGED_ELEMENT_' . strtoupper($element) . '--}</li>';
+               }
        } // END - foreach
        $OUT .= '</ol>';
 
@@ -185,10 +266,10 @@ function doAjaxInstallerChangeWarning () {
 
        if (in_array(postRequestElement('button'), array('previous', 'next'))) {
                // Load 'prefixed' template
-               setAjaxReplyContent(loadTemplate('install_warning_' . postRequestElement('button'), true, $content));
+               setAjaxReplyContent(loadTemplate('install_warning_' . postRequestElement('button'), TRUE, $content));
        } else {
                // Load 'tab' template
-               setAjaxReplyContent(loadTemplate('install_warning_tab', true, $content));
+               setAjaxReplyContent(loadTemplate('install_warning_tab', TRUE, $content));
        }
 
        // All okay if we reach this point
@@ -207,7 +288,7 @@ function doAjaxInstallerSaveChanges () {
        $currentTab = postRequestElement('tab');
 
        // Remove some elements which should not be saved
-       foreach (array('do', 'level') as $removedElement) {
+       foreach (array('tab', 'do', 'level') as $removedElement) {
                // Remove this element from POST data
                unsetPostRequestElement($removedElement);
        } // END - foreach
@@ -217,16 +298,17 @@ function doAjaxInstallerSaveChanges () {
                'status'        => 'failed',
                'message'       => '{--INSTALLER_SAVE_CHANGES_FAILED--}',
                // Don't set this to false, or else it will be returned as 'failed' but is saved
-               'is_saved'      => true,
+               'is_saved'      => TRUE,
                'failed_fields' => array()
        );
 
        // Init overall status
-       $isAllSaved = true;
+       $isAllSaved = TRUE;
 
        // Now set all remaining data in session
        foreach (postRequestArray() as $key => $value) {
                // Set it, if it is valid, else it will be added to $saveStatus (call-by-reference)
+               //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'key=' . $key . ',value[' . gettype($value) . '=' . $value);
                $saveStatus['is_saved'] = (
                        // Is the data valid?
                        (isInstallerDataValid($saveStatus, $key, $value))
@@ -236,12 +318,12 @@ function doAjaxInstallerSaveChanges () {
                );
 
                // Save the overall status for below final check
-               $isAllSaved = (($isAllSaved === true) && ($saveStatus['is_saved'] === true));
-               //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'key=' . $key . ',value=' . $value . ',is_saved=' . intval($saveStatus['is_saved']) . ',isAllSaved=' . intval($isAllSaved));
+               $isAllSaved = (($isAllSaved === TRUE) && ($saveStatus['is_saved'] === TRUE));
+               //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'key=' . $key . ',value[' . gettype($value) . '=' . $value . ',is_saved=' . intval($saveStatus['is_saved']) . ',isAllSaved=' . intval($isAllSaved));
        } // END - foreach
 
        // 'is_saved' is still true?
-       if ($isAllSaved === true) {
+       if ($isAllSaved === TRUE) {
                // Set 'done' and message
                $saveStatus['status']  = 'done';
                $saveStatus['message'] = '{--INSTALLER_SAVE_CHANGES_DONE--}';
@@ -251,12 +333,16 @@ function doAjaxInstallerSaveChanges () {
        } // END - if
 
        // Output the status array for JSON reply
-       setAjaxReplyContent(json_encode($saveStatus, JSON_FORCE_OBJECT));
+       setAjaxReplyContent(encodeJson($saveStatus));
 
        // All okay if we reach this point
        setHttpStatus('200 OK');
 }
 
+// ----------------------------------------------------------------------------
+//          Call-back functions for preparing installer page requests
+// ----------------------------------------------------------------------------
+
 // Prepare AJAX request 'welcome'
 function doAjaxPrepareInstallerWelcome () {
        // Kept empty to prevent logfile entry
@@ -322,21 +408,21 @@ function doAjaxPrepareInstallerDatabaseConfig () {
        } // END - if
 
        // Is 'mysql_dbase' not set?
-       if (!isSessionVariableSet('mysql_pass1')) {
+       if (!isSessionVariableSet('mysql_password1')) {
                // Then set it directly
-               setSession('mysql_pass1', '');
+               setSession('mysql_password1', '');
        } // END - if
 
-       // Is 'mysql_pass2' not set?
-       if (!isSessionVariableSet('mysql_pass2')) {
+       // Is 'mysql_password2' not set?
+       if (!isSessionVariableSet('mysql_password2')) {
                // Then set it directly
-               setSession('mysql_pass2', '');
+               setSession('mysql_password2', '');
        } // END - if
 
-       // Is 'mysql_type' not set?
-       if (!isSessionVariableSet('mysql_type')) {
+       // Is 'mysql_engine' not set?
+       if (!isSessionVariableSet('mysql_engine')) {
                // Then set it directly
-               setSession('mysql_type', 'MyISAM');
+               setSession('mysql_engine', 'MyISAM');
        } // END - if
 }
 
@@ -372,6 +458,21 @@ function doAjaxPrepareInstallerOtherConfig () {
        } // END - if
 }
 
+// Prepare AJAX request 'extensions'
+function doAjaxPrepareInstallerExtensions () {
+       // Is 'extensions' set?
+       if (!isSessionVariableSet('extensions')) {
+               /*
+                * At least ext-sql_patches and ext-task should be installed
+                *(ext-sql_patches is a must!)
+                */
+               setSession('extensions', 'admins:sql_patches:task');
+       } elseif (strpos(getSession('extensions'), 'sql_patches') === FALSE) {
+               // Add missing ext-sql_patches
+               setSession('extensions', getSession('extensions') . ':sql_patches');
+       }
+}
+
 // Prepare AJAX request 'overview'
 function doAjaxPrepareInstallerOverview () {
        // 'tab' must always be set to create a post-check-callback
@@ -390,39 +491,36 @@ function doAjaxPrepareInstallerOverview () {
                // Status message (e.g. for output)
                'message'       => '{--INSTALLER_OVERVIEW_FINAL_CHECK_FAILED--}',
                // Don't set this to false, or else it will be returned as 'failed' but is saved
-               'is_valid'      => true,
+               'is_valid'      => TRUE,
                // Failed fields
                'failed_fields' => array()
        );
 
        // Init overall status and final output
-       $isAllValid = true;
+       $isAllValid = TRUE;
        $output     = '';
 
        // Check all data in session
-       foreach (getSessionArray() as $key => $value) {
-               // Skip 'mailer_theme', 'tab' and 'installer'
-               if (in_array($key, array('mailer_theme', 'tab', 'installer'))) {
-                       // Skip this
-                       continue;
-               } // END - if
+       foreach (array_keys($GLOBALS['installer_groups']) as $key) {
+               // Get values from session
+               $value = getSession($key);
 
                // Is the data valid?
                $verificationStatus['is_valid'] = (isInstallerDataValid($verificationStatus, $key, $value));
 
                // Is this step okay?
-               if ($verificationStatus['is_valid'] === true) {
+               if ($verificationStatus['is_valid'] === TRUE) {
                        // Add this key/value pair to a overview group
                        addKeyValueToInstallerOverviewGroup($key, $value);
                } // END - if
 
                // Save the overall status for below final check
                //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'key=' . $key . ',value=' . $value . ',is_valid=' . intval($verificationStatus['is_valid']) . ',isAllValid=' . intval($isAllValid));
-               $isAllValid = (($isAllValid === true) && ($verificationStatus['is_valid'] === true));
+               $isAllValid = (($isAllValid === TRUE) && ($verificationStatus['is_valid'] === TRUE));
        } // END - foreach
 
        // Is it still true?
-       if ($isAllValid === true) {
+       if ((isInstallationDataCompleted()) && ($isAllValid === TRUE)) {
                // Set 'done' and message
                $verificationStatus['status']  = 'done';
                $verificationStatus['message'] = '{--INSTALLER_OVERVIEW_FINAL_CHECK_DONE--}';
@@ -434,27 +532,140 @@ function doAjaxPrepareInstallerOverview () {
        // Is it still valid?
        if ($verificationStatus['status'] != 'done') {
                // Log message away
-               logDebugMessage(__FUNCTION__, __LINE__, 'Final check on all stored data failed. message=' . $verificationStatus['message']);
+               //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'Final check on all stored data failed. message=' . $verificationStatus['message']);
+
+               // Process failed fields
+               $verificationStatus['failed_fields'] = handleInstallerFailedFields($verificationStatus['failed_fields']);
 
                // Output the array for JSON reply
-               setAjaxReplyContent(json_encode($verificationStatus, JSON_FORCE_OBJECT));
+               setAjaxReplyContent(loadTemplate('install_overview_failed', TRUE, $verificationStatus));
 
                /*
                 * Something went wrong, this might happen when e.g. the user has tried
                 * to save invalid database login data but hit reload button on error
                 * message.
                 */
-               setHttpStatus('500 Internal Server Error');
+               setHttpStatus('200 OK');
 
                // Abort here
                return;
        } // END - if
+}
 
-       // Output final rendered content
-       setAjaxReplyContent($output);
+// ----------------------------------------------------------------------------
+//            Call-back functions for doing installation steps
+// ----------------------------------------------------------------------------
 
-       // All okay if we reach this point
-       setHttpStatus('200 OK');
+// Call-back function to import first tables.sql file
+function doAjaxInstallerStepImportTablesSql () {
+       // Establish database link
+       establishAjaxInstallerDatabaseLink();
+
+       // Init SQL array
+       initSqls();
+
+       // Import tables.sql
+       importInstallSqlDump('tables');
+
+       // Are some SQLs found?
+       if (countSqls() == 0) {
+               // Abort here
+               reportBug(__FUNCTION__, __LINE__, '{--INSTALLER_SQL_IMPORT_FAILED--}');
+       } // END - if
+
+       // Now run all queries through
+       runFilterChain('run_sqls');
+
+       // Close SQL link
+       SQL_CLOSE(__FUNCTION__, __LINE__);
+}
+
+// Call-back function to import menu SQL file
+function doAjaxInstallerStepImportMenuSql () {
+       // Establish database link
+       establishAjaxInstallerDatabaseLink();
+
+       // Init SQL array
+       initSqls();
+
+       // Import tables.sql
+       importInstallSqlDump('menu-' . getLanguage());
+
+       // Are some SQLs found?
+       if (countSqls() == 0) {
+               // Abort here
+               reportBug(__FUNCTION__, __LINE__, '{--INSTALLER_SQL_IMPORT_FAILED--}');
+       } // END - if
+
+       // Now run all queries through
+       runFilterChain('run_sqls');
+
+       // Close SQL link
+       SQL_CLOSE(__FUNCTION__, __LINE__);
+}
+
+// Call-back function to install some important extensions
+function doAjaxInstallerStepInstallExtensions () {
+       // Only one element is required
+       if (!isSessionVariableSet('extensions')) {
+               // Some required session data is not set
+               reportBug(__FUNCTION__, __LINE__, 'Required session data for this step not found.');
+       } // END - if
+
+       // Establish database link
+       establishAjaxInstallerDatabaseLink();
+
+       // Get all extensions
+       $extensions = explode(':', getSession('extensions'));
+
+       // Make sure ext-sql_patches is first
+       array_unshift($extensions, 'sql_patches');
+
+       // "Walk" through all extensions
+       foreach ($extensions as $key => $ext_name) {
+               // Is ext-sql_patches not at key=0?
+               if (($key == 0) && ($ext_name == 'sql_patches')) {
+                       // Then skip this entry
+                       continue;
+               } elseif ((!loadExtension($ext_name, 'test', '0.0.0', TRUE)) || (!registerExtension($ext_name, NULL))) {
+                       // Didn't work
+                       reportBug(__FUNCTION__, __LINE__, 'Cannot load/register extension ' . $ext_name . '.');
+               } // END - if
+       } // END - foreach
+}
+
+// Call-back function to write local configuration file
+function doAjaxInstallerStepWriteLocalConfig () {
+       // Is all set?
+       if (!isSessionDataSet(array('base_path', 'base_url', 'main_title', 'slogan', 'webmaster', 'mysql_host', 'mysql_dbase', 'mysql_prefix', 'mysql_login', 'mysql_password1', 'mysql_password2', 'mysql_engine', 'output_mode', 'warn_no_pass', 'write_footer', 'enable_backlink'))) {
+               // Some required session data is not set
+               reportBug(__FUNCTION__, __LINE__, 'Required session data for this step not found.');
+       } // END - if
+
+       // Write config file
+       if (!doInstallWriteLocalConfigurationFile(
+               getSession('base_path'),
+               getSession('base_url'),
+               getSession('main_title'),
+               getSession('slogan'),
+               getSession('webmaster'),
+               getSession('warn_no_pass'),
+               getSession('write_footer'),
+               getSession('enable_backlink'),
+               getSession('mysql_host'),
+               getSession('mysql_dbase'),
+               getSession('mysql_login'),
+               getSession('mysql_password1'),
+               getSession('mysql_prefix'),
+               getSession('mysql_engine'),
+               getSession('smtp_host'),
+               getSession('smtp_user'),
+               getSession('smtp_password1')
+       )) {
+               // Something bad went wrong
+               removeFile(getSession('base_path') . getCachePath() . 'config-local.php');
+               reportBug(__FUNCTION__, __LINE__, 'Did not fully write config-local.php .');
+       }
 }
 
 // [EOF]