2 /************************************************************************
3 * Mailer v0.2.1-FINAL Start: 06/24/2012 *
4 * =================== Last change: 06/24/2012 *
6 * -------------------------------------------------------------------- *
7 * File : ajax_installer.php *
8 * -------------------------------------------------------------------- *
9 * Short description : AJAX-related functions for installer *
10 * -------------------------------------------------------------------- *
11 * Kurzbeschreibung : AJAX-bezogene Funktionen fuer Installer *
12 * -------------------------------------------------------------------- *
13 * Copyright (c) 2003 - 2009 by Roland Haeder *
14 * Copyright (c) 2009 - 2013 by Mailer Developer Team *
15 * For more information visit: http://mxchange.org *
17 * This program is free software; you can redistribute it and/or modify *
18 * it under the terms of the GNU General Public License as published by *
19 * the Free Software Foundation; either version 2 of the License, or *
20 * (at your option) any later version. *
22 * This program is distributed in the hope that it will be useful, *
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
25 * GNU General Public License for more details. *
27 * You should have received a copy of the GNU General Public License *
28 * along with this program; if not, write to the Free Software *
29 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, *
31 ************************************************************************/
33 // Some security stuff...
34 if (!defined('__SECURITY')) {
36 } elseif ((!isAjaxOutputMode()) || (!isInstaller())) {
37 header('HTTP/1.1 403 Forbidden');
38 die(json_encode(array('reply_content' => 'Access forbidden'), JSON_FORCE_OBJECT));
41 //-----------------------------------------------------------------------------
42 // Generic call-back functions, they all rely on session data
43 //-----------------------------------------------------------------------------
45 // Establish a database link
46 function establishAjaxInstallerDatabaseLink () {
47 // This requires some session data
48 if (!isSessionDataSet(array('mysql_host', 'mysql_dbase', 'mysql_prefix', 'mysql_login', 'mysql_password1', 'mysql_password2', 'mysql_engine', 'database_extension'))) {
49 // Some required session data is not set
50 reportBug(__FUNCTION__, __LINE__, 'Required session data for this step not found.');
53 // Remove any previous flag
54 unsetSqlLinkUp(__FUNCTION__, __LINE__);
57 $linkResource = sqlConnectToDatabase(getSession('mysql_host'), getSession('mysql_login'), getSession('mysql_password1'), __FUNCTION__, __LINE__);
59 // Is this a link resource?
60 if (!isValidSqlLink($linkResource)) {
62 reportBug(__FUNCTION__, __LINE__, 'linkResource[]=' . gettype($linkResource) . ', expected: link resource');
63 } elseif (!isSqlLinkUp()) {
65 reportBug(__FUNCTION__, __LINE__, 'Could not bring up SQL link.');
68 // Does selecting the database work?
69 if (!sqlSelectDatabase(getSession('mysql_dbase'), __FUNCTION__, __LINE__)) {
70 // Could not be selected
71 reportBug(__FUNCTION__, __LINE__, 'Could not select database ' . getSession('mysql_dbase'));
72 } elseif (!isInstallerSqlsReadable(getSession('base_path'))) {
73 // Installation area not found
74 reportBug(__FUNCTION__, __LINE__, 'SQL dumps not found. Please extract ALL files from the archive or checkout all files out from SVN.');
75 } elseif (ifFatalErrorsDetected()) {
76 // Some other fatal error occured
77 reportBug(__FUNCTION__, __LINE__, 'Some fatal error detected, please check debug.log for details.');
80 // Set type, prefix from POST data and database name for later queries
81 setConfigEntry('_TABLE_TYPE' , getSession('mysql_engine'));
82 setConfigEntry('_DB_TYPE' , getSession('database_extension'));
83 setConfigEntry('_MYSQL_PREFIX', getSession('mysql_prefix'));
84 setConfigEntry('__DB_NAME' , getSession('mysql_dbase'));
87 //-----------------------------------------------------------------------------
88 // Call-back functions for processing AJAX requests
89 //-----------------------------------------------------------------------------
91 // Processes AJAX requests for installer
92 function doAjaxProcessInstall () {
93 // 'do' must always be set and installation phase must be true
95 // This shall not happen
96 reportBug(__FUNCTION__, __LINE__, 'This AJAX request handler was called outside the installer.');
97 } elseif (!isPostRequestElementSet('do')) {
98 // This shall not happen
99 reportBug(__FUNCTION__, __LINE__, 'The JavaScript did not send "do" which is fatal.');
102 // Notify all modules that we are installing
103 $GLOBALS['__mailer_installing'] = TRUE;
105 // Again we do a call-back, so generate a function name depending on 'do'
106 $callbackName = 'doAjaxInstaller' . capitalizeUnderscoreString(postRequestElement('do'));
107 $GLOBALS['ajax_callback_function'] = $callbackName;
109 // Is the call-back function there?
110 if (!function_exists($callbackName)) {
111 // This shall not happen
112 reportBug(__FUNCTION__, __LINE__, 'AJAX call-back ' . $callbackName . ' does not exist.');
116 call_user_func($callbackName);
118 // Is the status fine or template not found (404)?
122 // Processes installer request for testing
123 function doAjaxInstallerTest () {
124 // Load the "test passed" template
125 setAjaxReplyContent(loadTemplate('ajax_test_passed', TRUE));
127 // All okay if we reach this point
128 setHttpStatus('200 OK');
131 // Processes installer requests for footer navigation
132 function doAjaxInstallerFooterNavigation () {
133 // 'tab' must always be set to determine which navigation buttons shall be visible
134 if (!isPostRequestElementSet('tab')) {
135 // This shall not happen
136 reportBug(__FUNCTION__, __LINE__, 'The JavaScript did not send "tab" which is fatal.');
139 // Init array for footer navigation
140 $enabledNavigations = array();
142 // "Detect" the 'tab' value
143 switch (postRequestElement('tab')) {
144 case 'base_data': // Also 'previous' is valid
145 case 'database_config':
150 array_push($enabledNavigations, 'previous');
151 case 'welcome': // Only 'next' works for welcome page
152 array_push($enabledNavigations, 'next');
155 case 'overview': // Enable only 'previous'
156 array_push($enabledNavigations, 'previous');
157 if (isInstallationDataCompleted()) {
159 array_push($enabledNavigations, 'finish');
163 default: // Unsupported value
164 // This shall not happen
165 reportBug(__FUNCTION__, __LINE__, 'Unsupported "tab" value ' . postRequestElement('tab') . ' detected.');
167 // This will never be reached
171 // Output the array for JSON reply
172 setAjaxReplyContent(encodeJson($enabledNavigations));
174 // All okay if we reach this point
175 setHttpStatus('200 OK');
178 // Processes installer AJAX calls for content-requests
179 function doAjaxInstallerDoStep () {
180 // 'step' must be there
181 if (!isPostRequestElementSet('step')) {
182 // This shall not happen
183 reportBug(__FUNCTION__, __LINE__, 'The JavaScript did not send "step" which is fatal.');
186 // Construct call-back name
187 $callbackName = 'doAjaxInstallerStep' . capitalizeUnderscoreString(postRequestElement('step'));
189 // Is the function there?
190 if (function_exists($callbackName)) {
191 // Call it for setting values in session
192 $status = call_user_func($callbackName);
194 // Log missing functions
195 reportBug(__FUNCTION__, __LINE__, 'Call-back function ' . $callbackName . ' does not exist.');
198 // Did the installation step went fine?
199 if ($status === TRUE) {
201 setAjaxReplyContent(encodeJson(postRequestElement('step') . '=OK'));
203 // All okay if we reach this point
204 setHttpStatus('200 OK');
208 // Processes installer AJAX calls for content-requests
209 function doAjaxInstallerRequestContent () {
210 // 'tab' must be there
211 if (!isPostRequestElementSet('tab')) {
212 // This shall not happen
213 reportBug(__FUNCTION__, __LINE__, 'The JavaScript did not send "tab" which is fatal.');
216 // Construct call-back name for value-preset
217 $callbackName = 'doAjaxPrepareInstaller' . capitalizeUnderscoreString(postRequestElement('tab'));
219 // Is the function there?
220 if (function_exists($callbackName)) {
221 // Call it for setting values in session
222 call_user_func($callbackName);
224 // Log missing functions
225 reportBug(__FUNCTION__, __LINE__, 'Call-back function ' . $callbackName . ' does not exist.');
228 // Is the HTTP status still the same? (204 No Content)
229 if (getHttpStatus() == '204 No Content') {
230 // We use the current access level 'install' as prefix and construct a template name
231 setAjaxReplyContent(loadTemplate('install_page_' . trim(postRequestElement('tab')), TRUE));
233 // Has the template been loaded?
234 if (isset($GLOBALS['template_content']['html']['install_page_' . trim(postRequestElement('tab'))])) {
235 // All okay if we reach this point
236 setHttpStatus('200 OK');
239 setHttpStatus('404 Not Found');
244 // Process installer AJAX call for change-warning
245 function doAjaxInstallerChangeWarning () {
246 // 'elements' and 'button' must be there
247 if ((!isPostRequestElementSet('elements')) || (!isPostRequestElementSet('button'))) {
248 // This shall not happen
249 reportBug(__FUNCTION__, __LINE__, 'The JavaScript did not send "elements" and/or "button" which is fatal.');
252 // "Walk" through all elements
254 foreach (explode(':', postRequestElement('elements')) as $element) {
255 // Is it an extension?
256 if (substr($element, 0, 4) == 'ext_') {
257 // Add row for extension
258 $OUT .= '<li>{%message,INSTALLER_CHANGED_ELEMENT_EXTENSION=' . str_replace('_', '-', $element) . '%}</li>';
261 $OUT .= '<li>{--INSTALLER_CHANGED_ELEMENT_' . strtoupper($element) . '--}</li>';
269 'button' => postRequestElement('button'),
270 'message' => '{--INSTALLER_TAB_NAVIGATION_' . strtoupper(postRequestElement('button')) . '_LINK--}',
273 if (in_array(postRequestElement('button'), array('previous', 'next'))) {
274 // Load 'prefixed' template
275 setAjaxReplyContent(loadTemplate('install_warning_' . postRequestElement('button'), TRUE, $content));
277 // Load 'tab' template
278 setAjaxReplyContent(loadTemplate('install_warning_tab', TRUE, $content));
281 // All okay if we reach this point
282 setHttpStatus('200 OK');
285 // Process installer AJAC call for saving changes
286 function doAjaxInstallerSaveChanges () {
287 // 'tab' must always be set to create a post-check-callback
288 if (!isPostRequestElementSet('tab')) {
289 // This shall not happen
290 reportBug(__FUNCTION__, __LINE__, 'The JavaScript did not send "tab" which is fatal.');
293 // Save the tab for pre-"filtering"
294 $currentTab = postRequestElement('tab');
296 // Remove some elements which should not be saved
297 foreach (array('tab', 'do', 'level') as $removedElement) {
298 // Remove this element from POST data
299 unsetPostRequestElement($removedElement);
302 // Default is failed save attempt (e.g. nothing to save)
304 'status' => 'failed',
305 'message' => '{--INSTALLER_SAVE_CHANGES_FAILED--}',
306 // Don't set this to false, or else it will be returned as 'failed' but is saved
308 'failed_fields' => array()
311 // Init overall status
314 // Now set all remaining data in session
315 foreach (postRequestArray() as $key => $value) {
316 // Set it, if it is valid, else it will be added to $saveStatus (call-by-reference)
317 //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'key=' . $key . ',value[' . gettype($value) . '=' . $value);
318 $saveStatus['is_saved'] = (
319 // Is the data valid?
320 (isInstallerDataValid($saveStatus, $key, $value))
322 // And can it be stored in session?
323 (setSessionCompiled($key, $value))
326 // Save the overall status for below final check
327 $isAllSaved = (($isAllSaved === TRUE) && ($saveStatus['is_saved'] === TRUE));
328 //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'key=' . $key . ',value[' . gettype($value) . '=' . $value . ',is_saved=' . intval($saveStatus['is_saved']) . ',isAllSaved=' . intval($isAllSaved));
331 // 'is_saved' is still true?
332 if ($isAllSaved === TRUE) {
333 // Set 'done' and message
334 $saveStatus['status'] = 'done';
335 $saveStatus['message'] = '{--INSTALLER_SAVE_CHANGES_DONE--}';
337 // Then do the post-check
338 doInstallerPostCheck($currentTab, $saveStatus);
341 // Output the status array for JSON reply
342 setAjaxReplyContent(encodeJson($saveStatus));
344 // All okay if we reach this point
345 setHttpStatus('200 OK');
348 // ----------------------------------------------------------------------------
349 // Call-back functions for preparing installer page requests
350 // ----------------------------------------------------------------------------
352 // Prepare AJAX request 'welcome'
353 function doAjaxPrepareInstallerWelcome () {
354 // Kept empty to prevent logfile entry
357 // Prepare AJAX request 'base_data'
358 function doAjaxPrepareInstallerBaseData () {
359 // Is 'base_path' not set?
360 if (!isSessionVariableSet('base_path')) {
361 // Then set it from PATH
362 setSessionCompiled('base_path', getPath());
365 // Is 'base_url' not set?
366 if (!isSessionVariableSet('base_url')) {
367 // Then set it from URL
368 setSessionCompiled('base_url', getUrl());
371 // Is 'main_title' not set?
372 if (!isSessionVariableSet('main_title')) {
373 // Then set it from default main title
374 setSessionCompiled('main_title', compileRawCode(getMessage('DEFAULT_MAIN_TITLE')));
377 // Is 'slogan' not set?
378 if (!isSessionVariableSet('slogan')) {
379 // Then set it from default slogan
380 setSessionCompiled('slogan', compileRawCode(getMessage('DEFAULT_SLOGAN')));
383 // Is 'webmaster' not set?
384 if (!isSessionVariableSet('webmaster')) {
385 // Then set it from default webmaster email address
386 setSessionCompiled('webmaster', '{--DEFAULT_WEBMASTER--}');
390 // Prepare AJAX request 'database_config'
391 function doAjaxPrepareInstallerDatabaseConfig () {
392 // Is 'mysql_host' not set?
393 if (!isSessionVariableSet('mysql_host')) {
394 // Then set it directly
395 setSessionCompiled('mysql_host', 'localhost');
398 // Is 'mysql_dbase' not set?
399 if (!isSessionVariableSet('mysql_dbase')) {
400 // Then set it directly
401 setSessionCompiled('mysql_dbase', 'your_database');
404 // Is 'mysql_prefix' not set?
405 if (!isSessionVariableSet('mysql_prefix')) {
406 // Then set it directly
407 setSessionCompiled('mysql_prefix', 'mailer');
410 // Is 'mysql_login' not set?
411 if (!isSessionVariableSet('mysql_login')) {
412 // Then set it directly
413 setSessionCompiled('mysql_login', 'your_login');
416 // Is 'mysql_dbase' not set?
417 if (!isSessionVariableSet('mysql_password1')) {
418 // Then set it directly
419 setSessionCompiled('mysql_password1', '');
422 // Is 'mysql_password2' not set?
423 if (!isSessionVariableSet('mysql_password2')) {
424 // Then set it directly
425 setSessionCompiled('mysql_password2', '');
428 // Is 'mysql_engine' not set?
429 if (!isSessionVariableSet('mysql_engine')) {
430 // Then set it directly
431 setSessionCompiled('mysql_engine', 'MyISAM');
434 // Is 'mysql_engine' not set?
435 if (!isSessionVariableSet('database_extension')) {
436 // Then set it directly
437 setSessionCompiled('database_extension', 'mysqli');
441 // Prepare AJAX request 'smtp_config'
442 function doAjaxPrepareInstallerSmtpConfig () {
443 // Kept empty to prevent logfile entry because SMTP settings are optional
446 // Prepare AJAX request 'other_config'
447 function doAjaxPrepareInstallerOtherConfig () {
448 // Is 'output_mode' not set?
449 if (!isSessionVariableSet('output_mode')) {
450 // Then set it directly
451 setSessionCompiled('output_mode', 'render');
454 // Is 'warn_no_pass' not set?
455 if (!isSessionVariableSet('warn_no_pass')) {
456 // Then set it directly
457 setSessionCompiled('warn_no_pass', 'Y');
460 // Is 'write_footer' not set?
461 if (!isSessionVariableSet('write_footer')) {
462 // Then set it directly
463 setSessionCompiled('write_footer', 'Y');
466 // Is 'enable_backlink' not set?
467 if (!isSessionVariableSet('enable_backlink')) {
468 // Then set it directly
469 setSessionCompiled('enable_backlink', 'Y');
473 // Prepare AJAX request 'extensions'
474 function doAjaxPrepareInstallerExtensions () {
475 // Is 'extensions' set?
476 if (!isSessionVariableSet('extensions')) {
478 * At least ext-admins, ext-sql_patches and ext-task should be installed
479 * (ext-sql_patches is a must!)
481 setSessionCompiled('extensions', 'admins:sql_patches:task');
482 } elseif (strpos(getSession('extensions'), 'sql_patches') === FALSE) {
483 // Add missing ext-sql_patches
484 setSessionCompiled('extensions', getSession('extensions') . ':sql_patches');
488 // Prepare AJAX request 'first_admin'
489 function doAjaxPrepareInstallerFirstAdmin () {
490 // Is 'admin_login' set?
491 if (!isSessionVariableSet('admin_login')) {
493 setSessionCompiled('admin_login', 'admin');
496 // Is 'admin_email' set?
497 if (!isSessionVariableSet('admin_email')) {
499 setSessionCompiled('admin_email', getSession('webmaster'));
502 // Is 'admin_password1' set?
503 if (!isSessionVariableSet('admin_password1')) {
505 setSessionCompiled('admin_password1', '');
508 // Is 'admin_password2' set?
509 if (!isSessionVariableSet('admin_password2')) {
511 setSessionCompiled('admin_password2', '');
515 // Prepare AJAX request 'overview'
516 function doAjaxPrepareInstallerOverview () {
517 // 'tab' must always be set to create a post-check-callback
518 if (!isPostRequestElementSet('tab')) {
519 // This shall not happen
520 reportBug(__FUNCTION__, __LINE__, 'The JavaScript did not send "tab" which is fatal.');
523 // Save the tab for pre-"filtering"
524 $currentTab = postRequestElement('tab');
526 // Default is failed save attempt (e.g. nothing to save)
527 $verificationStatus = array(
528 // Status code, can be 'failed' or 'done'
529 'status' => 'failed',
530 // Status message (e.g. for output)
531 'message' => '{--INSTALLER_OVERVIEW_FINAL_CHECK_FAILED--}',
532 // Don't set this to false, or else it will be returned as 'failed' but is saved
535 'failed_fields' => array()
538 // Init overall status and final output
542 // Check all data in session
543 foreach (array_keys($GLOBALS['installer_groups']) as $key) {
544 // Get values from session
545 $value = getSession($key);
547 // Is the data valid?
548 $verificationStatus['is_valid'] = (isInstallerDataValid($verificationStatus, $key, $value));
550 // Is this step okay?
551 if ($verificationStatus['is_valid'] === TRUE) {
552 // Add this key/value pair to a overview group
553 addKeyValueToInstallerOverviewGroup($key, $value);
556 // Save the overall status for below final check
557 //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'key=' . $key . ',value=' . $value . ',is_valid=' . intval($verificationStatus['is_valid']) . ',isAllValid=' . intval($isAllValid));
558 $isAllValid = (($isAllValid === TRUE) && ($verificationStatus['is_valid'] === TRUE));
562 if ((isInstallationDataCompleted()) && ($isAllValid === TRUE)) {
563 // Set 'done' and message
564 $verificationStatus['status'] = 'done';
565 $verificationStatus['message'] = '{--INSTALLER_OVERVIEW_FINAL_CHECK_DONE--}';
567 // Then do the post-check
568 doInstallerPostCheck($currentTab, $verificationStatus);
571 // Is it still valid?
572 if ($verificationStatus['status'] != 'done') {
574 //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'Final check on all stored data failed. message=' . $verificationStatus['message']);
576 // Process failed fields
577 $verificationStatus['failed_fields'] = handleInstallerFailedFields($verificationStatus['failed_fields']);
579 // Output the array for JSON reply
580 setAjaxReplyContent(loadTemplate('install_overview_failed', TRUE, $verificationStatus));
583 * Something went wrong, this might happen when e.g. the user has tried
584 * to save invalid database login data but hit reload button on error
587 setHttpStatus('200 OK');
594 // ----------------------------------------------------------------------------
595 // Call-back functions for doing installation steps
596 // ----------------------------------------------------------------------------
598 // Call-back function to import first tables.sql file
599 function doAjaxInstallerStepImportTablesSql () {
600 // Establish database link
601 establishAjaxInstallerDatabaseLink();
607 importInstallSqlDump('tables');
609 // Are some SQLs found?
610 if (countSqls() == 0) {
612 reportBug(__FUNCTION__, __LINE__, '{--INSTALLER_SQL_IMPORT_FAILED--}');
615 // Now run all queries through
616 runFilterChain('run_sqls');
619 sqlCloseLink(__FUNCTION__, __LINE__);
625 // Call-back function to import menu SQL file
626 function doAjaxInstallerStepImportMenuSql () {
627 // Establish database link
628 establishAjaxInstallerDatabaseLink();
634 importInstallSqlDump('menu-' . getLanguage());
636 // Are some SQLs found?
637 if (countSqls() == 0) {
639 reportBug(__FUNCTION__, __LINE__, '{--INSTALLER_SQL_IMPORT_FAILED--}');
642 // Now run all queries through
643 runFilterChain('run_sqls');
646 sqlCloseLink(__FUNCTION__, __LINE__);
652 // Call-back function to install some important extensions
653 function doAjaxInstallerStepInstallExtensions () {
654 // Only one element is required
655 if (!isSessionVariableSet('extensions')) {
656 // Some required session data is not set
657 reportBug(__FUNCTION__, __LINE__, 'Required session data for this step not found.');
660 // Establish database link
661 establishAjaxInstallerDatabaseLink();
663 // Get all extensions
664 $extensions = explode(':', getSession('extensions'));
666 // Make sure ext-sql_patches is first
667 array_unshift($extensions, 'sql_patches');
669 // "Walk" through all extensions
670 foreach ($extensions as $key => $ext_name) {
671 // Is ext-sql_patches not at key=0?
672 if (($key == 0) && ($ext_name == 'sql_patches')) {
673 // Then skip this entry
675 } elseif ((!loadExtension($ext_name, 'test', '0.0.0', TRUE)) || (!registerExtension($ext_name, NULL))) {
677 reportBug(__FUNCTION__, __LINE__, 'Cannot load/register extension ' . $ext_name . '.');
685 // Call-back function to write local configuration file
686 function doAjaxInstallerStepWriteLocalConfig () {
688 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', 'database_extension', 'output_mode', 'warn_no_pass', 'write_footer', 'enable_backlink'))) {
689 // Some required session data is not set
690 reportBug(__FUNCTION__, __LINE__, 'Required session data for this step not found.');
691 } elseif (isInstalled()) {
692 // Is already installed = local config written
693 reportBug(__FUNCTION__, __LINE__, 'Local config file is already written.');
694 } elseif (isAdminRegistered()) {
695 // Admin is already registered
696 reportBug(__FUNCTION__, __LINE__, 'First administrator account is already registered.');
699 // Establish database link
700 establishAjaxInstallerDatabaseLink();
703 if (!doInstallWriteLocalConfigurationFile(
704 getSession('base_path'),
705 getSession('base_url'),
706 getSession('main_title'),
707 getSession('slogan'),
708 getSession('webmaster'),
709 getSession('warn_no_pass'),
710 getSession('write_footer'),
711 getSession('enable_backlink'),
712 getSession('mysql_host'),
713 getSession('mysql_dbase'),
714 getSession('mysql_login'),
715 getSession('mysql_password1'),
716 getSession('mysql_prefix'),
717 getSession('mysql_engine'),
718 getSession('database_extension'),
719 getSession('smtp_host'),
720 getSession('smtp_user'),
721 getSession('smtp_password1')
723 // Something bad went wrong
724 removeFile(getSession('base_path') . getCachePath() . 'config-local.php');
725 reportBug(__FUNCTION__, __LINE__, 'Did not fully write config-local.php .');
728 // Change ADMIN_REGISTERED flag
729 $done = changeDataInLocalConfigurationFile('ADMIN-SETUP', "setConfigEntry('ADMIN_REGISTERED', '", "');", 'Y', 0);
735 // Call-back function to register first admin
736 function doAjaxInstallerStepRegisterFirstAdmin () {
738 if (!isSessionDataSet(array('admin_login', 'admin_email', 'admin_password1', 'admin_password2'))) {
739 // Some required session data is not set
740 reportBug(__FUNCTION__, __LINE__, 'Required session data for this step not found.');
741 } elseif (isAdminRegistered()) {
742 // First admin is already registered
743 reportBug(__FUNCTION__, __LINE__, 'First administrator is already registered.');
746 // Establish database link
747 establishAjaxInstallerDatabaseLink();
749 // Load admin include
750 loadIncludeOnce('inc/modules/admin/admin-inc.php');
752 // Register first admin
753 $ret = addAdminAccount(getSession('admin_login'), md5(getSession('admin_password1')), getSession('admin_email'), 'allow');
756 return ($ret == 'done');