2 /************************************************************************
3 * Mailer v0.2.1-FINAL Start: 10/22/2009 *
4 * =================== Last change: 10/22/2009 *
6 * -------------------------------------------------------------------- *
7 * File : install-functions.php *
8 * -------------------------------------------------------------------- *
9 * Short description : Functions for installation procedure *
10 * -------------------------------------------------------------------- *
11 * Kurzbeschreibung : Funktionen fuer die Installationsroutine *
12 * -------------------------------------------------------------------- *
13 * Copyright (c) 2003 - 2009 by Roland Haeder *
14 * Copyright (c) 2009 - 2016 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')) || (!isInstaller())) {
39 function initInstaller () {
40 // Initialize installer group array
41 $GLOBALS['installer_groups'] = array(
43 'base_path' => 'base_data',
44 'base_url' => 'base_data',
45 'main_title' => 'base_data',
46 'slogan' => 'base_data',
47 'webmaster' => 'base_data',
49 'mysql_host' => 'database_config',
50 'mysql_dbase' => 'database_config',
51 'mysql_prefix' => 'database_config',
52 'mysql_engine' => 'database_config',
53 'mysql_login' => 'database_config',
54 'mysql_password1' => 'database_config',
55 'mysql_password2' => 'database_config',
57 'smtp_host' => 'smtp_config',
58 'smtp_user' => 'smtp_config',
59 'smtp_password1' => 'smtp_config',
60 'smtp_password2' => 'smtp_config',
62 'output_mode' => 'other_config',
63 'warn_no_pass' => 'other_config',
64 'write_footer' => 'other_config',
65 'enable_backlink' => 'other_config',
67 'admin_login' => 'first_admin',
68 'admin_email' => 'first_admin',
69 'admin_password1' => 'first_admin',
70 'admin_password2' => 'first_admin',
73 // Set mininmum password length/score and other config entries
74 setConfigEntry('min_password_length', 5);
75 setConfigEntry('min_password_score' , 3);
76 setConfigEntry('verbose_sql' , 'N');
79 // Installer bootstrap
80 function doInstallerBootstrap () {
81 // Default output is 'direct' for HTML output
82 setConfigEntry('OUTPUT_MODE', 'direct');
84 // This hack prevents a backtrace in CSS output
85 if (isCssOutputMode()) {
86 // Problem with config so set output mode
87 setConfigEntry('OUTPUT_MODE', 'render');
91 /* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'isAjaxOutputMode()=' . intval(isAjaxOutputMode()) . ',isSessionVariableSet(database_extension)=' . intval(isSessionVariableSet('database_extension')));
93 // Is it AJAX call and database_extension is set?
94 if ((isAjaxOutputMode()) && (isSessionVariableSet('database_extension'))) {
95 // Then take it from session
96 /* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'Setting _DB_TYPE from session;database_extension=' . getSession('database_extension'));
97 setConfigEntry('_DB_TYPE', getSession('database_extension'));
98 } elseif (isPhpExtensionLoaded('mysqli')) {
100 /* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'Setting _DB_TYPE to MySQLi ...');
103 setConfigEntry('_DB_TYPE', 'mysqli');
104 } elseif (isPhpExtensionLoaded('mysql')) {
106 /* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'Setting _DB_TYPE to default (mysql) ...');
109 setConfigEntry('_DB_TYPE', 'mysql');
111 // Opps, cannot detect it?
112 reportBug(__FUNCTION__, __LINE__, 'Cannot detect mysql/mysqli. Please fix your setup.');
116 unsetSqlLinkUp(__FUNCTION__, __LINE__);
118 // Load database layer here
119 loadIncludeOnce('inc/db/lib.php');
121 // Init message system
128 foreach (array('databases', 'install-functions', 'load_config', 'load_cache') as $inc) {
130 loadIncludeOnce('inc/' . $inc . '.php');
136 // Check whether we are in installation routine
137 if ((!isInstalling()) && (!isCssOutputMode()) && (!isRawOutputMode())) {
138 // Redirect to the URL
139 redirectToUrl('install.php');
143 // Write the local config-local.php file from "template"
144 function doInstallWriteLocalConfigurationFile ($path, $url, $title, $slogan, $email, $noPassword, $writeFooter, $backLink, $databaseHost, $databaseName, $databaseLogin, $databasePassword, $databasePrefix, $tableType, $databaseExtension, $smtpHost, $smtpUser, $smtpPassword) {
145 // Copy the config template and verify it
146 copyFileVerified($path . 'inc/config-local.php.dist', $path . getCachePath() . 'config-local.php', 0644);
149 * Ok, all done. So we can write the config data to the php files. Do only
150 * write these if they differ from auto-detected values.
152 if ($path != getPath()) {
153 changeDataInLocalConfigurationFile('SERVER-PATH', "setConfigEntry('PATH', '", "');", $path, 0);
155 if ($url != getUrl()) {
156 changeDataInLocalConfigurationFile('HOST-URL', "setConfigEntry('URL', '", "');", $url, 0);
160 changeDataInLocalConfigurationFile('MAIN-TITLE', "setConfigEntry('MAIN_TITLE', '", "');", $title, 0);
161 changeDataInLocalConfigurationFile('SLOGAN', "setConfigEntry('SLOGAN', '", "');", $slogan, 0);
162 changeDataInLocalConfigurationFile('WEBMASTER', "setConfigEntry('WEBMASTER', '", "');", $email, 0);
163 changeDataInLocalConfigurationFile('NULLPASS-WARNING', "setConfigEntry('WARN_NO_PASS', '", "');", $noPassword, 0);
164 changeDataInLocalConfigurationFile('WRITE-FOOTER', "setConfigEntry('WRITE_FOOTER', '", "');", $writeFooter, 0);
165 changeDataInLocalConfigurationFile('BACKLINK', "setConfigEntry('ENABLE_BACKLINK', '", "');", $backLink, 0);
166 // @TODO DEACTIVATED: changeDataInLocalConfigurationFile('OUTPUT-MODE', "setConfigEntry('OUTPUT_MODE', '", "');", postRequestElement('omode'), 0);
167 changeDataInLocalConfigurationFile('MYSQL-HOST', " 'host' => '", "',", $databaseHost, 0);
168 changeDataInLocalConfigurationFile('MYSQL-DBASE', " 'dbase' => '", "',", $databaseName, 0);
169 changeDataInLocalConfigurationFile('MYSQL-LOGIN', " 'login' => '", "',", $databaseLogin, 0);
170 changeDataInLocalConfigurationFile('MYSQL-PASSWORD', " 'password' => '", "',", $databasePassword, 0);
171 changeDataInLocalConfigurationFile('MYSQL-PREFIX', "setConfigEntry('_MYSQL_PREFIX', '", "');", $databasePrefix, 0);
172 changeDataInLocalConfigurationFile('TABLE-TYPE', "setConfigEntry('_TABLE_TYPE', '", "');", $tableType, 0);
173 changeDataInLocalConfigurationFile('DATABASE-TYPE', "setConfigEntry('_DB_TYPE', '", "');", $databaseExtension, 0);
174 changeDataInLocalConfigurationFile('SMTP-HOSTNAME', "setConfigEntry('SMTP_HOSTNAME', '", "');", $smtpHost, 0);
175 changeDataInLocalConfigurationFile('SMTP-USER', "setConfigEntry('SMTP_USER', '", "');", $smtpUser, 0);
176 changeDataInLocalConfigurationFile('SMTP-PASSWORD', "setConfigEntry('SMTP_PASSWORD', '", "');", $smtpPassword, 0);
178 // Generate a long site-key and write it
179 changeDataInLocalConfigurationFile('SITE-KEY', "setConfigEntry('SITE_KEY', '", "');", generatePassword(50), 0);
181 // Script is now installed
182 return changeDataInLocalConfigurationFile('INSTALLED', "setConfigEntry('MAILER_INSTALLED', '", "');", 'Y', 0);
185 // Adds a given template with content to install output stream
186 function addTemplateToInstallContent ($template, $content = array()) {
188 $out = loadTemplate($template, TRUE, $content);
191 addToInstallContent($out);
194 // Add it to install content
195 function addToInstallContent ($out) {
197 if (!isset($GLOBALS['install_content'])) {
199 $GLOBALS['install_content'] = $out;
202 $GLOBALS['install_content'] .= $out;
206 // Somewhat getter for installer content
207 function getInstallerContent () {
209 if (isset($GLOBALS['install_content'])) {
211 $content = $GLOBALS['install_content'];
213 // Nothing found, this needs fixing
214 $content = returnMessage('{--INSTALLER_CONTENT_404--}');
221 // Read a given SQL dump
222 function readSqlDump ($FQFN) {
224 $content = readFromFile($FQFN);
226 // Remove some unwanted chars
227 $content = str_replace(array(chr(13), PHP_EOL . PHP_EOL), array('', PHP_EOL), $content);
229 // Return the content
233 // Generates the installer menu by simply loading another template
234 function generateInstallerMenu () {
235 // Load installer menu template
236 $OUT = loadTemplate('install_menu', TRUE);
238 // Return loaded content
242 // Generate the install footer navigation by simply loading another template
243 function generateInstallerFooterNavigation () {
244 // Load installer menu template
245 $OUT = loadTemplate('install_footer', TRUE);
247 // Return loaded content
251 // Generate an option list for database types for given default value
252 function generateInstallerDatabaseTypeOptions () {
253 return generateOptions(
260 '{--INSTALLER_TABLE_TYPE_MYISAM--}',
261 '{--INSTALLER_TABLE_TYPE_INNODB--}'
263 getSession('mysql_engine')
267 // Generate an option list for database extensions for given default value
268 function generateInstallerDatabaseExtensionOptions () {
272 $foundExtensions = array();
275 $drivers = getArrayFromDirectory('inc/db/', 'lib-', FALSE, FALSE);
277 // Remove prefix + extension
278 foreach ($drivers as $key => $driver) {
280 $drivers[$key] = substr($driver, 4, -4);
282 // Is the corresponding extension loaded?
283 if (isPhpExtensionLoaded($drivers[$key])) {
285 array_push($foundExtensions, $drivers[$key]);
289 // Generate list for keys/values ("translations")
290 foreach ($foundExtensions as $extension) {
291 // Use it as direct key
292 array_push($keys, $extension);
294 // Add "translation" function around it as value
295 array_push($values, '{%pipe,translatePhpExtension=' . $extension . '%}');
298 // Get a directory list
299 return generateOptions(
303 getSession('database_extension')
307 // Generate an option list for output mode types for given default value
308 function generateInstallerOutputModeOptions ($defaultValue) {
309 return generateOptions(
311 array('render', 'direct'),
312 array('{--INSTALLER_MODE_RENDER--}', '{--INSTALLER_MODE_DIRECT--}'),
317 // Checks whether we have an AJAX-enabled installer which defaults to red pill
318 function isAjaxInstaller () {
319 // Get the session data and compare it against 'ajax'
320 $isAjaxInstaller = (getSession('installer') == 'ajax');
323 return $isAjaxInstaller;
326 // Checks whether we have an plain installer which defaults to red pill
327 function isPlainInstaller () {
328 // Get the session data and compare it against 'plain'
329 $isPlainInstaller = (getSession('installer') == 'plain');
332 return $isPlainInstaller;
335 // Handle all given failed fields
336 function handleInstallerFailedFields ($failedFields) {
337 // Don't do anything with no array or no entries
338 if (!isFilledArray($failedFields)) {
340 reportBug(__FUNCTION__, __LINE__, 'failedFields[]=' . gettype($failedFields) . ' verification failed');
345 foreach ($failedFields as $key => $field) {
347 $out .= '<li>{--INSTALLER_FIELD_FAILED_' . strtoupper($field) . '--}</li>';
355 // Checks given key/value pair if it is valid by a call-back
356 function isInstallerDataValid (&$saveStatus, $key, $value) {
357 //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'key=' . $key . ',value=' . $value . ' - ENTERED!');
358 // Generate call-back function based on given key
359 $callbackName = 'isInstaller' . capitalizeUnderscoreString($key) . 'Valid';
361 // Is the function there?
362 if (!function_exists($callbackName)) {
363 // Not found, which is not bad, but it means this data is always valid
364 //* NOISY-DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'Call-back function ' . $callbackName . ' not found. saveStatus[status]=' . $saveStatus['status'] . ', key=' . $key . ', value=' . $value);
366 // All fine (CAREFULL!)
371 $isValid = (bool) call_user_func($callbackName, $value);
374 //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'key=' . $key . ',value=' . $value . ',isValid=' . intval($isValid));
375 if ($isValid === FALSE) {
376 // Then add it to saveStatus
377 array_push($saveStatus['failed_fields'], $key);
381 //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'key=' . $key . ',value=' . $value . ',isValid=' . intval($isValid) . ' - EXIT!');
385 // Post-check on installer data
386 function doInstallerPostCheck ($currentTab, &$saveStatus) {
388 //* NOISY-DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'currentTab=' . $currentTab . ',saveStatus[status]=' . $saveStatus['status'] . ' - ENTERED!');
390 // Create the call-back function on 'tab'
391 $callbackName = 'isInstallerPost' . capitalizeUnderscoreString($currentTab) . 'Valid';
393 // Is the function there?
394 if (!function_exists($callbackName)) {
395 // Not found, which is not bad, but it means the post-check won't be run
396 /* NOISY-DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'Call-back function ' . $callbackName . ' not found. saveStatus[status]=' . $saveStatus['status'] . ', currentTab=' . $currentTab);
402 // Init 'tab-specific error message'
403 $GLOBALS['installer_post_error'][$currentTab] = '';
404 $GLOBALS['installer_failed_fields'][$currentTab] = array();
407 //* NOISY-DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'Calling function ' . $callbackName . ',currentTab=' . $currentTab . ',saveStatus[status]=' . $saveStatus['status']);
410 $isValid = (bool) call_user_func($callbackName, $currentTab);
413 if (($isValid === FALSE) || (isFilledArray($GLOBALS['installer_failed_fields'][$currentTab]))) {
414 // Then change status and message
415 $saveStatus['status'] = 'failed';
416 $saveStatus['message'] = '{%message,INSTALLER_POST_CHECK_' . strtoupper($currentTab) . '_FAILED=' . $GLOBALS['installer_post_error'][$currentTab] . '%}';
418 // Is there failed fields?
419 if (isFilledArray($GLOBALS['installer_failed_fields'][$currentTab])) {
421 $saveStatus['failed_fields'] = merge_array($saveStatus['failed_fields'], $GLOBALS['installer_failed_fields'][$currentTab]);
426 //* NOISY-DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'currentTab=' . $currentTab . ',saveStatus[status]=' . $saveStatus['status'] . ' - EXIT!');
429 // Determines an installer group by given key
430 function determineInstallerGroupByKey ($key) {
432 if (!isset($GLOBALS['installer_groups'][$key])) {
434 logDebugMessage(__FUNCTION__, __LINE__, 'Cannot determine installer group, returning dummy group. key=' . $key);
436 // Return dummy group
441 return $GLOBALS['installer_groups'][$key];
444 // Adds given key/value pair to an overview group
445 function addKeyValueToInstallerOverviewGroup ($key, $value) {
446 // First determine the group by given key
447 $group = determineInstallerGroupByKey($key);
449 // Depending on the group, add it for later usage (to render the overview page)
450 $GLOBALS['installer_overview'][$group][$key] = $value;
453 //-----------------------------------------------------------------------------
454 // Template call-back functions
455 //-----------------------------------------------------------------------------
457 // ----------------- Extensions -----------------
459 // Generates (and returns) a table from all extensions
460 function generateInstallerExtensionTable () {
461 // Generate extension list
462 $extensions = loadAllExtensionsByTemplate();
464 // "Walk" through all
466 foreach ($extensions as $extension) {
467 // Remove prefix + suffix
468 $ext_name = substr(basename($extension), 4, -4);
470 // Is the extension not in development and not admintheme* ?
471 if ((loadExtension($ext_name, 'test', '0.0.0', TRUE)) && (isExtensionProductive($ext_name)) && (substr($ext_name, 0, 10) != 'admintheme')) {
472 // Default is not disabled
474 if (in_array($ext_name, array('sql_patches', 'timezone'))) {
475 // Always keep this enabled
476 $disabled = ' disabled="disabled"';
479 // Initialize content array
481 'ext_name' => $ext_name,
482 'ext_version' => getExtensionVersion($ext_name),
483 'checked' => getExtensionSelectedFromSession($ext_name, 'extensions'),
484 'disabled' => $disabled,
485 'description' => loadTemplate('ext_' . $ext_name, TRUE),
489 $OUT .= loadTemplate('install_list_extensions_row', TRUE, $content);
493 // Load main template
494 return loadTemplate('install_list_extensions', TRUE, $OUT);
497 //-----------------------------------------------------------------------------
498 // Call-back functions to check validity
499 //-----------------------------------------------------------------------------
501 // ----------------- Base data -----------------
503 // Call-back function to check validity of 'base_path'
504 function isInstallerBasePathValid ($value) {
505 //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'value=' . $value . ' - ENTERED!');
506 // Is it a directory and if some typical files could be found
508 // Is it a directory?
509 (isDirectory($value))
511 // Doesn't contain dots
512 (strpos($value, '..') === FALSE)
514 // Is there a trailing slash?
515 (substr($value, -1, 1) == '/')
517 // Is mysql-manager.php there?
518 (isFileReadable($value . 'inc/mysql-manager.php'))
520 // What about gen_sql_patches.php?
521 (isFileReadable($value . 'inc/gen_sql_patches.php'))
523 // And how about referral-functions.php?
524 (isFileReadable($value . 'inc/referral-functions.php'))
528 //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'value=' . $value . ',isValid=' . intval($isValid) . ' - EXIT');
532 // Call-back function to check validity of 'base_url'
533 function isInstallerBaseUrlValid ($value) {
534 //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'value=' . $value . ' - ENTERED!');
540 // Starts with http:// or https:// ?
541 (isFullQualifiedUrl($value))
543 // Has no trailing slash?
544 (substr($value, -1, 1) != '/')
546 // And total length is at least 6+8=14 chars long? (https://foo.ba)
547 (strlen($value) >= 14)
554 //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'value=' . $value . ',isValid=' . intval($isValid) . ' - EXIT');
558 // Call-back function to checl validity of 'main_title'
559 function isInstallerMainTitleValid ($value) {
561 // @TODO Comparing with DEFAULT_MAIN_TITLE doesn't work
562 $isValid = ((strlen($value) >= 4) && ($value != getMessage('DEFAULT_MAIN_TITLE')));
568 // Call-back function to checl validity of 'slogan'
569 function isInstallerSloganValid ($value) {
571 $isValid = ((strlen($value) >= 4) && ($value != getMessage('DEFAULT_SLOGAN')));
577 // Call-back function to check validity of 'webmaster'
578 function isInstallerWebmasterValid ($value) {
579 //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'value=' . $value . ' - ENTERED!');
580 // Is it a valid email address?
582 // Is it a valid email address?
583 (isEmailValid($value))
585 // Or is there 'localhost/127.0.0.1' as hostname? Then don't check email address (e.g. you@localhost)
586 (isDeveloperSystem())
588 // Is not default "email address"
589 $value != getMessage('DEFAULT_WEBMASTER')
595 //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'value=' . $value . ',isValid=' . intval($isValid) . ' - EXIT');
599 // ----------------- Database configuration -----------------
601 // Call-back function to check validity of 'mysql_host'
602 function isInstallerMysqlHostValid ($value) {
603 // This value must match a hostname or IP address
605 // Shall not be empty
606 (!empty($value)) && (
607 // Is localhost/127.0.0.1? (mostly the case)
608 (in_array($value, array('localhost', '127.0.0.1')))
610 // IP number match (this regex was taken from www.regexlib.com)
611 (preg_match('/((25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9]))/', $value))
614 (preg_match('/([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,6}/', $value))
621 // Call-back function to check validity of 'mysql_engine'
622 function isInstallerMysqlEngineValid ($value) {
623 // This value must be 'MyISAM' or 'InnoDB'
624 $isValid = in_array($value, array('MyISAM', 'InnoDB'));
630 // Call-back function to check validity of 'database_extension'
631 function isInstallerDatabaseExtensionValid ($value) {
632 // This value must be 'mysql' or 'mysqli'
633 $isValid = in_array($value, array('mysql', 'mysqli'));
639 // Call-back function to check validity of 'mysql_dbase'
640 function isInstallerMysqlDbaseValid ($value) {
641 // This value must not be empty
642 $isValid = ((!empty($value)) && ($value != 'your_database'));
648 // Call-back function to check validity of 'mysql_login'
649 function isInstallerMysqlLoginValid ($value) {
650 // This value must not be empty
651 $isValid = ((!empty($value)) && ($value != 'your_login'));
657 // Call-back function to check validity of 'mysql_prefix'
658 function isInstallerMysqlPrefixValid ($value) {
659 // This value must not be empty
660 $isValid = !empty($value);
666 // ----------------- SMTP configuration -----------------
668 // ----------------- Other configuration -----------------
670 // ----------------- First administator -----------------
672 // Call-back function to check validity of 'admin_login'
673 function isInstallerAdminLoginValid ($value) {
674 // Length should not be shorter than 4 characters
675 return (strlen($value) >= 4);
678 // Call-back function to check validity of 'admin_email'
679 function isInstallerAdminEmailValid ($value) {
680 // Just call webmaster-check function
681 return isInstallerWebmasterValid($value);
684 // Call-back function to check validity of 'admin_password1'
685 function isInstallerAdminPassword1Valid ($value) {
686 // Check if it is strong
687 return isStrongPassword($value);
690 // Call-back function to check validity of 'admin_password2'
691 function isInstallerAdminPassword2Valid ($value) {
692 // Check if it is strong
693 return isStrongPassword($value);
696 // ----------------- Extensions -----------------
698 // Call-back function to check 'sel' (array!)
699 function isInstallerSelValid ($value) {
700 // $value is not an array, is really bad.
701 if (!is_array($value)) {
703 reportBug(__FUNCTION__, __LINE__, 'sel,value[]=' . gettype($value) . '!=array');
706 // Add always missing ext-sql_patches
707 $value['sql_patches'] = '1';
712 // "Walk" through all extensions
713 foreach ($value as $ext_name => $sel) {
714 // Is this extension choosen?
721 $isValid = (($isValid) && (loadExtension($ext_name, 'test', '0.0.0', TRUE)));
724 // Remove 'sel' from POST data as it cannot be saved
725 unsetPostRequestElement('sel');
727 // Save it in session (sorry to do that here :( )
728 setSession('extensions', implode(':', array_keys($value)));
734 //-----------------------------------------------------------------------------
735 // Call-back functions to post-check validity
736 //-----------------------------------------------------------------------------
738 // Call-back function to check if base data is valid
739 function isInstallerPostBaseDataValid ($currentTab) {
740 // By default it is not valid
743 // Is the base path valid?
744 if (!isInstallerBasePathValid(postRequestElement('base_path'))) {
746 $GLOBALS['installer_post_error'][$currentTab] = '{--INSTALLER_POST_BASE_PATH_INVALID--}';
747 array_push($GLOBALS['installer_failed_fields'][$currentTab], 'base_path');
749 } elseif (!isInstallerBaseUrlValid(postRequestElement('base_url'))) {
751 $GLOBALS['installer_post_error'][$currentTab] = '{--INSTALLER_POST_BASE_URL_INVALID--}';
752 array_push($GLOBALS['installer_failed_fields'][$currentTab], 'base_url');
754 } elseif (strlen(postRequestElement('main_title')) < 3) {
756 $GLOBALS['installer_post_error'][$currentTab] = '{--INSTALLER_POST_MAIN_TITLE_INVALID--}';
757 array_push($GLOBALS['installer_failed_fields'][$currentTab], 'main_title');
759 } elseif (strlen(postRequestElement('slogan')) < 3) {
761 $GLOBALS['installer_post_error'][$currentTab] = '{--INSTALLER_POST_SLOGAN_INVALID--}';
762 array_push($GLOBALS['installer_failed_fields'][$currentTab], 'slogan');
764 } elseif (!isInstallerWebmasterValid(postRequestElement('webmaster'))) {
766 $GLOBALS['installer_post_error'][$currentTab] = '{--INSTALLER_POST_WEBMASTER_INVALID--}';
767 array_push($GLOBALS['installer_failed_fields'][$currentTab], 'webmaster');
773 // Remember this tab in session
774 installTabOkay($currentTab);
781 // Call-back function to check if database configuration in POST is valid
782 function isInstallerPostDatabaseConfigValid ($currentTab) {
783 // By default nothing is valid
785 $engineValid = FALSE;
788 // Do both passwords match?
789 if ((!isPostRequestElementSet('mysql_password1')) && (isPostRequestElementSet('mysql_password2'))) {
790 // Password 1 not set
791 $GLOBALS['installer_post_error'][$currentTab] = '{--INSTALLER_POST_DATABASE_PASSWORD1_EMPTY--}';
792 array_push($GLOBALS['installer_failed_fields'][$currentTab], 'mysql_password1');
794 } elseif ((isPostRequestElementSet('mysql_password1')) && (!isPostRequestElementSet('mysql_password2'))) {
795 // Password 2 not set
796 $GLOBALS['installer_post_error'][$currentTab] = '{--INSTALLER_POST_DATABASE_PASSWORD2_EMPTY--}';
797 array_push($GLOBALS['installer_failed_fields'][$currentTab], 'mysql_password2');
799 } elseif (postRequestElement('mysql_password1') != postRequestElement('mysql_password2')) {
800 // Passwords mismatch
801 $GLOBALS['installer_post_error'][$currentTab] = '{--INSTALLER_POST_DATABASE_PASSWORDS_MISMATCH--}';
802 array_push($GLOBALS['installer_failed_fields'][$currentTab], 'mysql_password1', 'mysql_password2');
806 // Remove any previous flag
807 unsetSqlLinkUp(__FUNCTION__, __LINE__);
809 // Try to connect to the database
810 sqlConnectToDatabase(postRequestElement('mysql_host'), postRequestElement('mysql_login'), postRequestElement('mysql_password1'), __FUNCTION__, __LINE__);
813 if (!isSqlLinkUp()) {
814 // Cannot connect to database
815 $GLOBALS['installer_post_error'][$currentTab] = '{--INSTALLER_POST_DATABASE_CONNECT_ERROR--}';
816 array_push($GLOBALS['installer_failed_fields'][$currentTab], 'mysql_login', 'mysql_password1', 'mysql_password2');
820 // Then attempt to select the database
821 if (!sqlSelectDatabase(postRequestElement('mysql_dbase'), __FUNCTION__, __LINE__)) {
822 // Could not find database
823 $GLOBALS['installer_post_error'][$currentTab] = '{--INSTALLER_POST_DATABASE_SELECT_FAILED--}';
824 array_push($GLOBALS['installer_failed_fields'][$currentTab], 'mysql_dbase');
826 // Disconnect here, we don't need idle database connections laying around
827 sqlCloseLink(__FUNCTION__, __LINE__);
833 // Set database name and prefix
834 setConfigEntry('__DB_NAME' , postRequestElement('mysql_dbase'));
835 setConfigEntry('_MYSQL_PREFIX', postRequestElement('mysql_prefix'));
837 // Get an array of all supported engines
838 $engines = getArrayFromSupportedSqlEngines(postRequestElement('mysql_engine'));
841 if (!is_array($engines)) {
842 // Something bad happened
843 $GLOBALS['installer_post_error'][$currentTab] = '{--INSTALLER_POST_DATABASE_ENGINES_SQL_ERROR--}';
844 array_push($GLOBALS['installer_failed_fields'][$currentTab], 'mysql_engine');
846 // Disconnect here, we don't need idle database connections laying around
847 sqlCloseLink(__FUNCTION__, __LINE__);
851 } elseif (!isFilledArray($engines)) {
852 // No engine is active
853 $GLOBALS['installer_post_error'][$currentTab] = '{--INSTALLER_POST_DATABASE_NO_ENGINES_ACTIVE--}';
854 array_push($GLOBALS['installer_failed_fields'][$currentTab], 'mysql_engine');
856 // Disconnect here, we don't need idle database connections laying around
857 sqlCloseLink(__FUNCTION__, __LINE__);
863 // Then check all, if the requested is working
864 foreach ($engines as $engineArray) {
865 // By default the selected engine is not valid
866 $engineValid = FALSE;
868 // Is the engine there?
869 if (strtolower($engineArray['Engine']) == strtolower(postRequestElement('mysql_engine'))) {
870 // Okay, engine is found
876 // So, is the engine found?
877 if ($engineValid === FALSE) {
878 // Requested engine is not active
879 $GLOBALS['installer_post_error'][$currentTab] = '{--INSTALLER_POST_DATABASE_ENGINE_UNSUPPORTED--}';
880 array_push($GLOBALS['installer_failed_fields'][$currentTab], 'mysql_engine');
882 // Disconnect here, we don't need idle database connections laying around
883 sqlCloseLink(__FUNCTION__, __LINE__);
889 // Init some known tables
894 'admin_menu' => TRUE,
900 'extensions' => TRUE,
902 'guest_menu' => TRUE,
904 'max_receive' => TRUE,
906 'member_menu' => TRUE,
920 'task_system' => TRUE,
923 // So check if all tables are not there
924 foreach ($tables as $tableName => $isFound) {
926 $tables[$tableName] = ifSqlTableExists($tableName);
928 // Is it (hopefully not) there?
929 if ($tables[$tableName] === FALSE) {
930 // This does not exist
935 // Determine final status (simply compare both counts
936 $isValid = (count($tables) == $missingTables);
938 // Disconnect here, we don't need idle database connections laying around
939 sqlCloseLink(__FUNCTION__, __LINE__);
941 // If the status is true, disconnect the database
942 if ($isValid === FALSE) {
943 // Still something bad happened (e.g. tables found)
944 $GLOBALS['installer_post_error'][$currentTab] = '{--INSTALLER_POST_DATABASE_IN_USE--}';
945 array_push($GLOBALS['installer_failed_fields'][$currentTab], 'mysql_dbase');
947 // Remember this tab in session
948 installTabOkay($currentTab);
955 // Call-back function to check if first admin data is valid
956 function isInstallerPostFirstAdminValid ($currentTab) {
957 // Is all data valid?
958 if (!isPostRequestElementSet('admin_login')) {
960 $GLOBALS['installer_post_error'][$currentTab] = '{--INSTALLER_POST_FIRST_ADMIN_LOGIN_EMPTY--}';
961 array_push($GLOBALS['installer_failed_fields'][$currentTab], 'admin_login');
963 } elseif (strlen(postRequestElement('admin_login')) < 4) {
965 $GLOBALS['installer_post_error'][$currentTab] = '{--INSTALLER_POST_FIRST_ADMIN_LOGIN_SHORT--}';
966 array_push($GLOBALS['installer_failed_fields'][$currentTab], 'admin_login');
968 } elseif (!isPostRequestElementSet('admin_email')) {
969 // Email address not set
970 $GLOBALS['installer_post_error'][$currentTab] = '{--INSTALLER_POST_FIRST_ADMIN_EMAIL_EMPTY--}';
971 array_push($GLOBALS['installer_failed_fields'][$currentTab], 'admin_email');
973 } elseif (!isInstallerAdminEmailValid(postRequestElement('admin_email'))) {
974 // Invalid email address
975 $GLOBALS['installer_post_error'][$currentTab] = '{--INSTALLER_POST_FIRST_ADMIN_EMAIL_INVALID--}';
976 array_push($GLOBALS['installer_failed_fields'][$currentTab], 'admin_email');
978 } elseif ((!isPostRequestElementSet('admin_password1')) && (isPostRequestElementSet('admin_password2'))) {
979 // Password 1 not set
980 $GLOBALS['installer_post_error'][$currentTab] = '{--INSTALLER_POST_FIRST_ADMIN_PASSWORD1_EMPTY--}';
981 array_push($GLOBALS['installer_failed_fields'][$currentTab], 'admin_password1');
983 } elseif ((isPostRequestElementSet('admin_password1')) && (!isPostRequestElementSet('admin_password2'))) {
984 // Password 2 not set
985 $GLOBALS['installer_post_error'][$currentTab] = '{--INSTALLER_POST_FIRST_ADMIN_PASSWORD2_EMPTY--}';
986 array_push($GLOBALS['installer_failed_fields'][$currentTab], 'admin_password2');
988 } elseif (postRequestElement('admin_password1') != postRequestElement('admin_password2')) {
989 // Passwords mismatch
990 $GLOBALS['installer_post_error'][$currentTab] = '{--INSTALLER_POST_FIRST_ADMIN_PASSWORDS_MISMATCH--}';
991 array_push($GLOBALS['installer_failed_fields'][$currentTab], 'admin_password1', 'admin_password2');
993 } elseif (!isStrongPassword(postRequestElement('admin_password1'))) {
994 // Weak passwords entered
995 $GLOBALS['installer_post_error'][$currentTab] = '{--INSTALLER_POST_FIRST_ADMIN_PASSWORDS_WEAK--}';
996 array_push($GLOBALS['installer_failed_fields'][$currentTab], 'admin_password1', 'admin_password2');
1004 // Store given tab in session
1005 function installTabOkay ($currentTab) {
1007 if (isSessionVariableSet('installer_okay')) {
1008 // Is this tab already found?
1009 if (strpos(getSession('installer_okay'), $currentTab) === FALSE) {
1011 setSession('installer_okay', getSession('installer_okay') . ';' . $currentTab);
1015 setSession('installer_okay', $currentTab);
1019 // Checks whether at least the required tabs are completed
1020 function isInstallationDataCompleted () {
1023 (isSessionVariableSet('installer_okay')) &&
1024 (strpos(getSession('installer_okay'), 'base_data') !== FALSE) &&
1025 (strpos(getSession('installer_okay'), 'database_config') !== FALSE)
1029 //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'isCompleted=' . intval($isCompleted) . ',installer_okay=' . getSession('installer_okay'));
1030 return $isCompleted;
1033 // Call-back function to check if enable_backlink is Y/N
1034 function isInstallerEnableBacklinkValid ($currentTab) {
1035 // Check and return it
1036 return in_array($currentTab, array('Y', 'N'));
1039 // Call-back function to check if warn_no_pass is Y/N
1040 function isInstallerWarnNoPassValid ($currentTab) {
1041 // Check and return it
1042 return in_array($currentTab, array('Y', 'N'));
1045 // Call-back function to check if write_footer is Y/N
1046 function isInstallerWriteFooterValid ($currentTab) {
1047 // Check and return it
1048 return in_array($currentTab, array('Y', 'N'));
1051 // Call-back function to check if output_mode is Y/N
1052 function isInstallerOutputModeValid ($currentTab) {
1053 // Check and return it
1054 return in_array($currentTab, array('render', 'direct'));
1057 // Wrapper to import given installation SQL dump
1058 function importInstallSqlDump ($dumpName) {
1060 importSqlDump('install', $dumpName, 'install');
1063 // Wrapper to check if tables.sql and menu-foo.sql are readable
1064 function isInstallerSqlsReadable ($path) {
1066 return ((isFileReadable($path . 'install/tables.sql')) && (isFileReadable($path . 'install/menu-' . getLanguage() . '.sql')));