X-Git-Url: https://git.mxchange.org/?p=mailer.git;a=blobdiff_plain;f=inc%2Fajax%2Fajax_installer.php;h=f1e7eb7aaa5d0f55b8119a98cac4fd560e08a8cd;hp=1f6f9fc2a2fcb115a5bc542ad332329ad062296e;hb=ca256746fe0757a23df4064824c8fe2087ad5634;hpb=63f159414369b5ea19a8ca75d8cd8033c45d8341 diff --git a/inc/ajax/ajax_installer.php b/inc/ajax/ajax_installer.php index 1f6f9fc2a2..f1e7eb7aaa 100644 --- a/inc/ajax/ajax_installer.php +++ b/inc/ajax/ajax_installer.php @@ -36,10 +36,53 @@ ************************************************************************/ // 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,21 +216,21 @@ 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['tpl_content']['install_page_' . trim(postRequestElement('tab'))])) { + if (isset($GLOBALS['template_content']['html']['install_page_' . trim(postRequestElement('tab'))])) { // All okay if we reach this point 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 = '
    '; foreach (explode(':', postRequestElement('elements')) as $element) { - // Add row - $OUT .= '
  1. {--INSTALLER_CHANGED_ELEMENT_' . strtoupper($element) . '--}
  2. '; + // Is it an extension? + if (substr($element, 0, 4) == 'ext_') { + // Add row for extension + $OUT .= '
  3. {%message,INSTALLER_CHANGED_ELEMENT_EXTENSION=' . str_replace('_', '-', $element) . '%}
  4. '; + } else { + // Add generic row + $OUT .= '
  5. {--INSTALLER_CHANGED_ELEMENT_' . strtoupper($element) . '--}
  6. '; + } } // END - foreach $OUT .= '
'; @@ -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]