'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 = sqlConnectToDatabase(getSession('mysql_host'), getSession('mysql_login'), getSession('mysql_password1'), __FUNCTION__, __LINE__); // Is this a link resource? if (!isValidSqlLink($linkResource)) { // Is not a resource reportBug(__FUNCTION__, __LINE__, 'linkResource[]=' . gettype($linkResource) . ', expected: link resource'); } elseif (!isSqlLinkUp()) { // SQL link is not up reportBug(__FUNCTION__, __LINE__, 'Could not bring up SQL link.'); } // Does selecting the database work? if (!sqlSelectDatabase(getSession('mysql_dbase'), __FUNCTION__, __LINE__)) { // Could not be selected reportBug(__FUNCTION__, __LINE__, 'Could not select database ' . getSession('mysql_dbase')); } elseif (!isInstallerSqlsReadable(getSession('base_path'))) { // 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.'); } // 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 //----------------------------------------------------------------------------- // Processes AJAX requests for installer function doAjaxProcessInstall () { // 'do' must always be set and installation phase must be true if (!isInstaller()) { // This shall not happen reportBug(__FUNCTION__, __LINE__, 'This AJAX request handler was called outside the installer.'); } elseif (!isPostRequestElementSet('do')) { // This shall not happen reportBug(__FUNCTION__, __LINE__, 'The JavaScript did not send "do" which is fatal.'); } // END - if // Notify all modules that we are installing $GLOBALS['__mailer_installing'] = TRUE; // Again we do a call-back, so generate a function name depending on 'do' $callbackName = 'doAjaxInstaller' . capitalizeUnderscoreString(postRequestElement('do')); $GLOBALS['ajax_callback_function'] = $callbackName; // Is the call-back function there? if (!function_exists($callbackName)) { // This shall not happen reportBug(__FUNCTION__, __LINE__, 'AJAX call-back ' . $callbackName . ' does not exist.'); } // END - if // Call the function call_user_func($callbackName); // Is the status fine or template not found (404)? sendAjaxContent(); } // Processes installer request for testing function doAjaxInstallerTest () { // Load the "test passed" template setAjaxReplyContent(loadTemplate('ajax_test_passed', TRUE)); // All okay if we reach this point setHttpStatus('200 OK'); } // Processes installer requests for footer navigation function doAjaxInstallerFooterNavigation () { // 'tab' must always be set to determine which navigation buttons shall be visible if (!isPostRequestElementSet('tab')) { // This shall not happen reportBug(__FUNCTION__, __LINE__, 'The JavaScript did not send "tab" which is fatal.'); } // END - if // Init array for footer navigation $enabledNavigations = array(); // "Detect" the 'tab' value switch (postRequestElement('tab')) { case 'base_data': // Also 'previous' is valid case 'database_config': case 'smtp_config': case 'other_config': case 'extensions': case 'first_admin': array_push($enabledNavigations, 'previous'); case 'welcome': // Only 'next' works for welcome page array_push($enabledNavigations, 'next'); break; case 'overview': // Enable only 'previous' array_push($enabledNavigations, 'previous'); if (isInstallationDataCompleted()) { // Add 'finish' array_push($enabledNavigations, 'finish'); } // END - if break; default: // Unsupported value // This shall not happen reportBug(__FUNCTION__, __LINE__, 'Unsupported "tab" value ' . postRequestElement('tab') . ' detected.'); // This will never be reached break; } // END - switch // Output the array for JSON reply 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 $status = call_user_func($callbackName); } else { // Log missing functions reportBug(__FUNCTION__, __LINE__, 'Call-back function ' . $callbackName . ' does not exist.'); } // Did the installation step went fine? if ($status === TRUE) { // All fine setAjaxReplyContent(encodeJson(postRequestElement('step') . '=OK')); // All okay if we reach this point setHttpStatus('200 OK'); } // END - if } // Processes installer AJAX calls for content-requests function doAjaxInstallerRequestContent () { // 'tab' must be there if (!isPostRequestElementSet('tab')) { // This shall not happen reportBug(__FUNCTION__, __LINE__, 'The JavaScript did not send "tab" which is fatal.'); } // END - if // Construct call-back name for value-preset $callbackName = 'doAjaxPrepareInstaller' . capitalizeUnderscoreString(postRequestElement('tab')); // 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.'); } // 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)); // Has the template been loaded? 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'); } } // END - if } // Process installer AJAX call for change-warning function doAjaxInstallerChangeWarning () { // 'elements' and 'button' must be there if ((!isPostRequestElementSet('elements')) || (!isPostRequestElementSet('button'))) { // This shall not happen reportBug(__FUNCTION__, __LINE__, 'The JavaScript did not send "elements" and/or "button" which is fatal.'); } // END - if // "Walk" through all elements $OUT = '
    '; foreach (explode(':', postRequestElement('elements')) as $element) { // Is it an extension? if (substr($element, 0, 4) == 'ext_') { // Add row for extension $OUT .= '
  1. {%message,INSTALLER_CHANGED_ELEMENT_EXTENSION=' . str_replace('_', '-', $element) . '%}
  2. '; } else { // Add generic row $OUT .= '
  3. {--INSTALLER_CHANGED_ELEMENT_' . strtoupper($element) . '--}
  4. '; } } // END - foreach $OUT .= '
'; // Prepare content $content = array( 'out' => $OUT, 'button' => postRequestElement('button'), 'message' => '{--INSTALLER_TAB_NAVIGATION_' . strtoupper(postRequestElement('button')) . '_LINK--}', ); if (in_array(postRequestElement('button'), array('previous', 'next'))) { // Load 'prefixed' template setAjaxReplyContent(loadTemplate('install_warning_' . postRequestElement('button'), TRUE, $content)); } else { // Load 'tab' template setAjaxReplyContent(loadTemplate('install_warning_tab', TRUE, $content)); } // All okay if we reach this point setHttpStatus('200 OK'); } // Process installer AJAC call for saving changes function doAjaxInstallerSaveChanges () { // 'tab' must always be set to create a post-check-callback if (!isPostRequestElementSet('tab')) { // This shall not happen reportBug(__FUNCTION__, __LINE__, 'The JavaScript did not send "tab" which is fatal.'); } // END - if // Save the tab for pre-"filtering" $currentTab = postRequestElement('tab'); // Remove some elements which should not be saved foreach (array('tab', 'do', 'level') as $removedElement) { // Remove this element from POST data unsetPostRequestElement($removedElement); } // END - foreach // Default is failed save attempt (e.g. nothing to save) $saveStatus = array( '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, 'failed_fields' => array() ); // Init overall status $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)) && // And can it be stored in session? (setSession($key, $value)) ); // Save the overall status for below final check $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) { // Set 'done' and message $saveStatus['status'] = 'done'; $saveStatus['message'] = '{--INSTALLER_SAVE_CHANGES_DONE--}'; // Then do the post-check doInstallerPostCheck($currentTab, $saveStatus); } // END - if // Output the status array for JSON reply 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 } // Prepare AJAX request 'base_data' function doAjaxPrepareInstallerBaseData () { // Is 'base_path' not set? if (!isSessionVariableSet('base_path')) { // Then set it from PATH setSession('base_path', getPath()); } // END - if // Is 'base_url' not set? if (!isSessionVariableSet('base_url')) { // Then set it from URL setSession('base_url', getUrl()); } // END - if // Is 'main_title' not set? if (!isSessionVariableSet('main_title')) { // Then set it from default main title setSession('main_title', compileRawCode(getMessage('DEFAULT_MAIN_TITLE'))); } // END - if // Is 'slogan' not set? if (!isSessionVariableSet('slogan')) { // Then set it from default slogan setSession('slogan', compileRawCode(getMessage('DEFAULT_SLOGAN'))); } // END - if // Is 'webmaster' not set? if (!isSessionVariableSet('webmaster')) { // Then set it from default webmaster email address setSession('webmaster', '{--DEFAULT_WEBMASTER--}'); } // END - if } // Prepare AJAX request 'database_config' function doAjaxPrepareInstallerDatabaseConfig () { // Is 'mysql_host' not set? if (!isSessionVariableSet('mysql_host')) { // Then set it directly setSession('mysql_host', 'localhost'); } // END - if // Is 'mysql_dbase' not set? if (!isSessionVariableSet('mysql_dbase')) { // Then set it directly setSession('mysql_dbase', 'your_database'); } // END - if // Is 'mysql_prefix' not set? if (!isSessionVariableSet('mysql_prefix')) { // Then set it directly setSession('mysql_prefix', 'mailer'); } // END - if // Is 'mysql_login' not set? if (!isSessionVariableSet('mysql_login')) { // Then set it directly setSession('mysql_login', 'your_login'); } // END - if // Is 'mysql_dbase' not set? if (!isSessionVariableSet('mysql_password1')) { // Then set it directly setSession('mysql_password1', ''); } // END - if // Is 'mysql_password2' not set? if (!isSessionVariableSet('mysql_password2')) { // Then set it directly setSession('mysql_password2', ''); } // END - if // Is 'mysql_engine' not set? if (!isSessionVariableSet('mysql_engine')) { // Then set it directly setSession('mysql_engine', 'MyISAM'); } // END - if } // Prepare AJAX request 'smtp_config' function doAjaxPrepareInstallerSmtpConfig () { // Kept empty to prevent logfile entry because SMTP settings are optional } // Prepare AJAX request 'other_config' function doAjaxPrepareInstallerOtherConfig () { // Is 'output_mode' not set? if (!isSessionVariableSet('output_mode')) { // Then set it directly setSession('output_mode', 'render'); } // END - if // Is 'warn_no_pass' not set? if (!isSessionVariableSet('warn_no_pass')) { // Then set it directly setSession('warn_no_pass', 'Y'); } // END - if // Is 'write_footer' not set? if (!isSessionVariableSet('write_footer')) { // Then set it directly setSession('write_footer', 'Y'); } // END - if // Is 'enable_backlink' not set? if (!isSessionVariableSet('enable_backlink')) { // Then set it directly setSession('enable_backlink', 'Y'); } // END - if } // Prepare AJAX request 'extensions' function doAjaxPrepareInstallerExtensions () { // Is 'extensions' set? if (!isSessionVariableSet('extensions')) { /* * At least ext-admins, 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 'first_admin' function doAjaxPrepareInstallerFirstAdmin () { // Is 'admin_login' set? if (!isSessionVariableSet('admin_login')) { // Set it setSession('admin_login', 'admin'); } // END - if // Is 'admin_email' set? if (!isSessionVariableSet('admin_email')) { // Set it setSession('admin_email', getSession('webmaster')); } // END - if // Is 'admin_password1' set? if (!isSessionVariableSet('admin_password1')) { // Set it setSession('admin_password1', ''); } // END - if // Is 'admin_password2' set? if (!isSessionVariableSet('admin_password2')) { // Set it setSession('admin_password2', ''); } // END - if } // Prepare AJAX request 'overview' function doAjaxPrepareInstallerOverview () { // 'tab' must always be set to create a post-check-callback if (!isPostRequestElementSet('tab')) { // This shall not happen reportBug(__FUNCTION__, __LINE__, 'The JavaScript did not send "tab" which is fatal.'); } // END - if // Save the tab for pre-"filtering" $currentTab = postRequestElement('tab'); // Default is failed save attempt (e.g. nothing to save) $verificationStatus = array( // Status code, can be 'failed' or 'done' 'status' => 'failed', // 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, // Failed fields 'failed_fields' => array() ); // Init overall status and final output $isAllValid = TRUE; $output = ''; // Check all data in session 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) { // 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)); } // END - foreach // Is it still true? if ((isInstallationDataCompleted()) && ($isAllValid === TRUE)) { // Set 'done' and message $verificationStatus['status'] = 'done'; $verificationStatus['message'] = '{--INSTALLER_OVERVIEW_FINAL_CHECK_DONE--}'; // Then do the post-check doInstallerPostCheck($currentTab, $verificationStatus); } // END - if // Is it still valid? if ($verificationStatus['status'] != 'done') { // Log message away //* 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(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('200 OK'); // Abort here return; } // END - if } // ---------------------------------------------------------------------------- // Call-back functions for doing installation steps // ---------------------------------------------------------------------------- // 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 sqlCloseLink(__FUNCTION__, __LINE__); // All fine return TRUE; } // 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 sqlCloseLink(__FUNCTION__, __LINE__); // All fine return TRUE; } // 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 // All fine return TRUE; } // 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.'); } elseif (isInstalled()) { // Is already installed = local config written reportBug(__FUNCTION__, __LINE__, 'Local config file is already written.'); } elseif (isAdminRegistered()) { // Admin is already registered reportBug(__FUNCTION__, __LINE__, 'First administrator account is already registered.'); } // Establish database link establishAjaxInstallerDatabaseLink(); // 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 .'); } // Change ADMIN_REGISTERED flag $done = changeDataInLocalConfigurationFile('ADMIN-SETUP', "setConfigEntry('ADMIN_REGISTERED', '", "');", 'Y', 0); // All fine return $done; } // Call-back function to register first admin function doAjaxInstallerStepRegisterFirstAdmin () { // Is all set? if (!isSessionDataSet(array('admin_login', 'admin_email', 'admin_password1', 'admin_password2'))) { // Some required session data is not set reportBug(__FUNCTION__, __LINE__, 'Required session data for this step not found.'); } elseif (isAdminRegistered()) { // First admin is already registered reportBug(__FUNCTION__, __LINE__, 'First administrator is already registered.'); } // Establish database link establishAjaxInstallerDatabaseLink(); // Load admin include loadIncludeOnce('inc/modules/admin/admin-inc.php'); // Register first admin $ret = addAdminAccount(getSession('admin_login'), md5(getSession('admin_password1')), getSession('admin_email'), 'allow'); // Did it work? return ($ret == 'done'); } // [EOF] ?>