This is an adaptation of the install.php script that is part of the SMF distribution. This is posted for illustrative purposes only. This script should not be distributed or incorporated into any working site, as it is incomplete. This is just here to illustrate some techniques that someone who wanted to integrate SMF with the Windows Web Application Gallery might want to consider implementing.
<?php
/**********************************************************************************
* silent install.php *
***********************************************************************************
* SMF: Simple Machines Forum *
* Open-Source Project Inspired by Zef Hemel (zef@zefhemel.com) *
* =============================================================================== *
* Software Version: SMF 1.1.9 *
* Software by: Simple Machines (http://www.simplemachines.org) *
* Copyright 2006-2009 by: Simple Machines LLC (http://www.simplemachines.org) *
* 2001-2006 by: Lewis Media (http://www.lewismedia.com) *
* Support, News, Updates at: http://www.simplemachines.org *
***********************************************************************************
* This program is free software; you may redistribute it and/or modify it under *
* the terms of the provided license as published by Simple Machines LLC. *
* *
* This program is distributed in the hope that it is and will be useful, but *
* WITHOUT ANY WARRANTIES; without even any implied warranty of MERCHANTABILITY *
* or FITNESS FOR A PARTICULAR PURPOSE. *
* *
* See the "license.txt" file for details of the Simple Machines license. *
* The latest version can always be found at http://www.simplemachines.org. *
***********************************************************************************
* NOTE - This is an adaptation of the install.php script that is part of the *
* SMF distribution. This is posted for illustrative purposes only. This script *
* should not be distributed or incorporated into any working site, as it is *
* incomplete. This is just here to illustrate some techniques that someone who *
* wanted to integrate SMF with the Windows Web Application Gallery might want *
* to consider implementing. *
**********************************************************************************/
$GLOBALS['current_smf_version'] = '1.1.9';
$GLOBALS['required_php_version'] = '4.1.0';
$GLOBALS['required_mysql_version'] = '3.23.28';
// Hardcoding the English language file for now.
require_once(dirname(__FILE__) . '/Themes/default/languages/Install.english.php');
//main routines
if (!doStep1())
{
die ('Step 1 failed');
}
if (!doStep2())
{
die ('Step 2 failed');
}
if (!cleanup())
{
die ('cleanup failed');
}
// NOTE - we're gone at this point.
header('Location: ' . $boardurl . '/index.php');
// Step one:
function doStep1()
{
global $txt, $db_prefix, $db_connection, $HTTP_SESSION_VARS, $cookiename;
global $func, $db_character_set, $mbname, $context, $scripturl, $boardurl;
global $current_smf_version,$db_name, $db_passwd, $db_server, $db_user;
require(dirname(__FILE__) . '/Settings.php');
$vars = array(
// The cookiename is special; we want it to be the same if it ever needs to be reinstalled with the same info.
'cookiename' => 'SMFCookie' . abs(crc32($db_name . preg_replace('~[^A-Za-z0-9_$]~', '', $db_prefix)) % 1000),
);
if (!updateSettingsFile($vars))
{
traceme();
return false;
}
// Make sure it works.
require(dirname(__FILE__) . '/Settings.php');
// Attempt a connection.
$db_connection = mysql_connect($db_server, $db_user, $db_passwd);
// Still no connection? Big fat error message :P.
if (!$db_connection)
{
traceme();
return false;
}
// Let's try that database on for size...
if ($db_name != '')
mysql_query("
CREATE DATABASE IF NOT EXISTS `$db_name`", $db_connection);
// Okay, let's try the prefix if it didn't work...
if (!mysql_select_db($db_name, $db_connection) )
{
traceme();
return false;
}
// Before running any of the queries, let's make sure another version isn't already installed.
// For this example, pulling out the version check - simplifying by assuming that the
// database will be new.
$replaces = array(
'{$db_prefix}' => $db_prefix,
'{$boarddir}' => addslashes(dirname(__FILE__)),
'{$boardurl}' => $boardurl,
'{$enableCompressedOutput}' => 'PlaceholderForEnableCompressedOutput',
'{$databaseSession_enable}' => 'PlaceholderForEnableDatabaseSessions',
'{$smf_version}' => $GLOBALS['current_smf_version'],
);
foreach ($txt as $key => $value)
{
if (substr($key, 0, 8) == 'default_')
$replaces['{$' . $key . '}'] = addslashes($value);
}
$replaces['{$default_reserved_names}'] = strtr($replaces['{$default_reserved_names}'], array('\\\\n' => '\\n'));
// Read in the SQL. Turn this on and that off... internationalize... etc.
$sql_lines = explode("\n", strtr(implode(' ', file(dirname(__FILE__) . '/install_1-1.sql')), $replaces));
// Execute the SQL.
$current_statement = '';
$failures = array();
$exists = array();
foreach ($sql_lines as $count => $line)
{
// No comments allowed!
if (substr(trim($line), 0, 1) != '#')
$current_statement .= "\n" . rtrim($line);
// Is this the end of the query string?
if (empty($current_statement) || (preg_match('~;[\s]*$~s', $line) == 0 && $count != count($sql_lines)))
continue;
// Does this table already exist? If so, don't insert more data into it!
if (preg_match('~^\s*INSERT INTO ([^\s\n\r]+?)~', $current_statement, $match) != 0 && in_array($match[1], $exists))
{
$current_statement = '';
continue;
}
if (mysql_query($current_statement) === false)
{
// Error 1050: Table already exists!
if (mysql_errno($db_connection) === 1050 && preg_match('~^\s*CREATE TABLE ([^\s\n\r]+?)~', $current_statement, $match) == 1)
$exists[] = $match[1];
else
$failures[$count] = mysql_error();
}
$current_statement = '';
}
// Maybe we can auto-detect better cookie settings?
preg_match('~^http[s]?://([^\.]+?)([^/]*?)(/.*)?$~', $mbname, $matches);
if (!empty($matches))
{
// Default = both off.
$localCookies = false;
$globalCookies = false;
// Okay... let's see. Using a subdomain other than www.? (not a perfect check.)
if ($matches[2] != '' && (strpos(substr($matches[2], 1), '.') === false || in_array($matches[1], array('forum', 'board', 'community', 'forums', 'support', 'chat', 'help', 'talk', 'boards', 'www'))))
$globalCookies = true;
// If there's a / in the middle of the path, or it starts with ~... we want local.
if (isset($matches[3]) && strlen($matches[3]) > 3 && (substr($matches[3], 0, 2) == '/~' || strpos(substr($matches[3], 1), '/') !== false))
$localCookies = true;
$rows = array();
if ($globalCookies)
$rows[] = "('globalCookies', '1')";
if ($localCookies)
$rows[] = "('localCookies', '1')";
if (!empty($rows))
mysql_query("
INSERT INTO {$db_prefix}settings
(variable, value)
VALUES " . implode(',
', $rows));
}
// As of PHP 5.1, setting a timezone is required.
if (!isset($modSettings['default_timezone']) && function_exists('date_default_timezone_set'))
{
$server_offset = mktime(0, 0, 0, 1, 1, 1970);
$timezone_id = 'Etc/GMT' . ($server_offset > 0 ? '+' : '') . ($server_offset / 3600);
if (date_default_timezone_set($timezone_id))
mysql_query("
REPLACE INTO {$db_prefix}settings
(variable, value)
VALUES
('default_timezone', '$timezone_id')");
}
// Let's optimize those new tables.
$tables = mysql_list_tables($db_name);
$table_names = array();
while ($table = mysql_fetch_row($tables))
$table_names[] = $table[0];
mysql_free_result($tables);
mysql_query('
OPTIMIZE TABLE `' . implode('`, `', $table_names) . '`') or $db_messed = true;
if (!empty($db_messed))
$failures[-1] = mysql_error($db_connection);
if (!empty($failures))
{
echo '
<div class="error_message">
<div style="color: red;">', $txt['error_mysql_queries'], '</div>
<div style="margin: 2.5ex;">';
foreach ($failures as $line => $fail)
echo '
<b>', $txt['error_mysql_queries_line'], $line + 1, ':</b> ', nl2br(htmlspecialchars($fail)), '<br />';
echo '
</div>
<a href="', $_SERVER['PHP_SELF'], '?step=0&overphp=true">', $txt['error_message_click'], '</a> ', $txt['error_message_try_again'], '
</div>';
traceme();
return false;
}
return true;
}
// Step two: Create the administrator, and finish.
function doStep2()
{
global $txt, $db_prefix, $db_connection, $HTTP_SESSION_VARS, $cookiename;
global $func, $db_character_set, $mbname, $context, $scripturl, $boardurl;
global $current_smf_version, $db_user, $db_server, $db_passwd, $sourcedir;
global $db_name;
// Load the SQL server login information.
require(dirname(__FILE__) . '/Settings.php');
$db_connection = @mysql_connect($db_server, $db_user, $db_passwd);
if (!$db_connection)
{
traceme();
return false;
}
if (!mysql_select_db($db_name, $db_connection))
{
traceme();
return false;
}
if (!file_exists($sourcedir . '/Subs.php'))
{
traceme();
return false;
}
updateSettingsFile(array('webmaster_email' => 'PlaceholderForWebmasterEmail'));
chdir(dirname(__FILE__));
define('SMF', 1);
require_once($sourcedir . '/Subs.php');
require_once($sourcedir . '/Load.php');
require_once($sourcedir . '/Security.php');
require_once($sourcedir . '/Subs-Auth.php');
// Define the sha1 function, if it doesn't exist.
if (!function_exists('sha1'))
require_once($sourcedir . '/Subs-Compat.php');
// Initialize some variables needed for the language file.
$context = array(
'forum_name' => $mbname,
);
$modSettings = array(
'lastActive' => '15',
'hotTopicPosts' => '15',
'hotTopicVeryPosts' => '25',
'smfVersion' => $current_smf_version,
);
$scripturl = $boardurl . '/index.php';
// Format the username properly.
$username='PlaceholderForUsername';
$username = preg_replace('~[\t\n\r\x0B\0\xA0]+~', ' ', $username);
$ip = isset($_SERVER['REMOTE_ADDR']) ? addslashes(substr(stripslashes($_SERVER['REMOTE_ADDR']), 0, 255)) : '';
$request = mysql_query("
INSERT INTO {$db_prefix}members
(memberName, realName, passwd, emailAddress, ID_GROUP, posts, dateRegistered, hideEmail, passwordSalt, lngfile, personalText, avatar, memberIP, memberIP2, buddy_list, pm_ignore_list, messageLabels, websiteTitle, websiteUrl, location, ICQ, MSN, signature, usertitle, secretQuestion, additionalGroups)
VALUES (SUBSTRING('$username', 1, 25), SUBSTRING('$username', 1, 25), '" . sha1(strtolower($username) . 'PlaceholderForPassword') . "', 'PlaceholderForWebmasterEmail', 1, '0', '" . time() . "', '0', '$salt', '', '', '', '$ip', '$ip', '', '', '', '', '', '', '', '', '', '', '', '')");
$id = mysql_insert_id();
return true;
}
function updateSettingsFile($vars)
{
// Modify Settings.php.
$settingsArray = file(dirname(__FILE__) . '/Settings.php');
// !!! Do we just want to read the file in clean, and split it this way always?
if (count($settingsArray) == 1)
$settingsArray = preg_split('~[\r\n]~', $settingsArray[0]);
for ($i = 0, $n = count($settingsArray); $i < $n; $i++)
{
// Remove the redirect...
if (trim($settingsArray[$i]) == 'if (file_exists(dirname(__FILE__) . \'/silent-install.php\'))')
{
$settingsArray[$i] = '';
$settingsArray[$i++] = '';
$settingsArray[$i++] = '';
continue;
}
elseif (substr(trim($settingsArray[$i]), -16) == '/silent-install.php\');' && substr(trim($settingsArray[$i]), 0, 26) == 'header(\'Location: http://\'')
{
$settingsArray[$i] = '';
continue;
}
if (trim($settingsArray[$i]) == '?' . '>')
$settingsArray[$i] = '';
// Don't trim or bother with it if it's not a variable.
if (substr($settingsArray[$i], 0, 1) != '$')
continue;
$settingsArray[$i] = rtrim($settingsArray[$i]) . "\n";
foreach ($vars as $var => $val)
if (strncasecmp($settingsArray[$i], '$' . $var, 1 + strlen($var)) == 0)
{
$comment = strstr($settingsArray[$i], '#');
$settingsArray[$i] = '$' . $var . ' = \'' . $val . '\';' . ($comment != '' ? "\t\t" . $comment : "\n");
unset($vars[$var]);
}
}
// Uh oh... the file wasn't empty... was it?
if (!empty($vars))
{
$settingsArray[$i++] = '';
foreach ($vars as $var => $val)
$settingsArray[$i++] = '$' . $var . ' = \'' . $val . '\';' . "\n";
}
// Blank out the file - done to fix a oddity with some servers.
$fp = @fopen(dirname(__FILE__) . '/Settings.php', 'w');
if (!$fp) {
traceme();
return false;
}
fclose($fp);
$fp = fopen(dirname(__FILE__) . '/Settings.php', 'r+');
if (!$fp) {
traceme();
return false;
}
// Gotta have one of these ;).
if (trim($settingsArray[0]) != '<?php')
fwrite($fp, "<?php\n");
$lines = count($settingsArray);
for ($i = 0; $i < $lines - 1; $i++)
{
// Don't just write a bunch of blank lines.
if ($settingsArray[$i] != '' || @$settingsArray[$i - 1] != '')
fwrite($fp, strtr($settingsArray[$i], "\r", ''));
}
fwrite($fp, $settingsArray[$i] . '?' . '>');
fclose($fp);
return true;
}
function cleanup()
{
$clean=unlink(__FILE__);
$clean+=unlink(dirname(__FILE__) . '/webinstall.php');
$clean+=unlink(dirname(__FILE__) . '/install_1-1.sql');
$clean+=unlink(dirname(__FILE__) . '/install.php');
if (!$clean) return false;
}
function traceme()
{
// Over simplified tracing routine. Should not be used in any production environment.
$tracedump=debug_backtrace();
echo "<HR><PRE>";
var_dump($tracedump);
echo "</PRE><HR>";
$logdump = var_export($tracedump,true);
$fd=fopen("C:\\Windows\\Temp\\silent.log","a");
fprintf($fd,"%s\n",$logdump);
fclose ($fd);
}
?>